2011-05-25 4 views
8

ルビースクリプトを実行している場所から現在のターミナルディレクトリを変更できるかどうかを知りたいと思います。ruby​​スクリプトからフォルダ内の(ターミナル)cd

たとえば、端末の$HOMEからスクリプトを実行している場合は、スクリプトの最後に$HOME/mydirでcdしたいと思います。

私はいくつかのことを試しましたが、私はいつもスクリプトが開始された同一の場所で探しています。私が試した

もの:

Dir.chdir(mydir) 
%[cd mydir] 

彼らは実際にだけスクリプトの実行のスレッドで、ディレクトリを変更します。スクリプトが終了すると、端末の私の現在の位置は、私がスクリプトを起動する前と同じです。

私はSOと同様のものを見つけましたが、Python-relatedです。応答は否定的です。


なぜか質問することがありますか?

私は現在、開始点としてプロジェクトフォルダが必要なコマンドラインアプリケーション(gliを使用しています)に携わっています。現在のディレクトリに名前projectで新しいフォルダを作成します

$ myfoo new project 

:だから私の最初のコマンドは次のようになります。今、私がする必要がある他のコマンドで作業できるようにするには:

$ cd project 
project$ myfoo domore 

だから私は単にmyfoo new projectを実行した後にprojectに私の自己を発見したのはいいだろうと考えていました。


私が恐れていたように、それは簡単ではありません(全く不可能です)。 RubyGemsによって生成された標準ファイルの代わりに、私が望むRuby呼び出しを実行するbashスクリプトを使うのはどうですか?それは実現可能ですか?私は愚かですか? evalを使用する必要がありますか?


回答ありがとうございます。しかし、私は誰も受け入れられないことを恐れています。おそらく質問はなかったでしょう:)。

+0

これを行うことはできないようです。 rubyからのシステムコールは、あなたのスクリプト/シェルとは異なるスレッドで動作し、現在の場所には影響しません。あなたはこれを使うために何を望んでいますか? –

+0

@ Douglas-F-Shearer:なぜ私の答えがちょっと好奇心から外れて –

+0

になってしまったのですが、どうして私の答えがうまくいかなかったのですか?私はこのテクニックを数回使いましたが、あなたの状況にどう対応していないのかはっきりしていません。 – Ian

答えて

2

私の知る限り、これは異なるプロセスなので、これは不可能です。 Rubyスクリプトの親プロセス(Bash)に影響を与える必要がある場合、Bashは何かを取得する必要があります。だから、あなたのRubyスクリプトにbashコマンドをいくつか出力し、Rubyの出力をソースとするBashラッパーを用意することができます。

バッシュで、一例として、これを試してみてください:

`ruby -e 'puts "cd /tmp"'` | source /dev/stdin 

But this will only work in Bash 4.0.

EDIT:

実は、あなたはevalの代わりのバッシュ3のソースでこれを行うことができます。

eval $(ruby -e'puts "cd /tmp"') 
+0

しかし、私はスクリプトで '%[eval $(ruby -e'puts" cd/tmp "')]'で終わります。これは何の違いもありません。 –

+0

右、あなたが子供のBashプロセス(あなたが影響を与えたいBashプロセスの孫)を産んでいるので、そこにあなたのコードを評価し、それを死に至らせます。変更したいBashプロセスでevalを直接実行する必要があります。後で、エイリアスなどで整理することができます。 – Ian

+0

私は物事を逆に求めている答えを広げました。 –

2

私はこれを行うための簡単な方法はないと思います。

ログインシェルからプログラムを起動すると、フードの下にfork/execが実行されます。これは新しい(子プロセス)が作成されたことを示します(現在の作業ディレクトリなどの独自の環境を持っています) /出力/エラーストリームは(親)シェルプロセスに関連付けられています。スクリプトがDir.chdirを呼び出すと、親ではなくスクリプト(子プロセス)の現在の作業ディレクトリが変更されます。

おそらくあなたのスクリプトは終了する前に新しいシェルを起動する可能性があるので、端末がディレクトリを変更したようです。しかし、ターミナルセッションを終了する前に余分なシェルを終了する必要があります...

+0

私は、そのことを他の方法で尋ねる答えを広げました。 –

0

Midnight Commanderは、シェルエイリアスとラッパースクリプトを使用してこれを行います。

ラッパーは、終了時にmc(1)によって書き込まれたファイルの内容によって決定されるディレクトリにcdするためのもので、代わりにsourceにラッパーが使用され、ログインシェルで実行されますフォークされたサブシェルのスクリプトが正常に起動されたかどうかを確認します。

これは、終了時に現在の作業ディレクトリを変更することができます。

これを行うには、エイリアス/ラッパー機能を複製する必要があります。彼らのやり方については、http://midnight-commander.org/browser/contribを参照してください。

+0

いくつかのドキュメントはありますか?これを私のユースケースにどのように適用すればよいですか? –

+0

これは私の答えと同じことです。 – Ian

1

たぶん少し簡単に、

あなたはこれを達成するためにルビーの内側に新しいbashシェルを作成する方法についてMaericsポストとの組み合わせでのexecを使用することができます。

exec ruby -e "Dir.chdir('mydir'); exec 'bash'" 

execので、シェルは、もはや(終了する必要が)存在しない、子プロセス(ルビー)と親プロセス(シェル)を交換しません。

ルビルーチンの終わりに、新しいディレクトリにbashが起動され(今度はrubyでexec)、ルビプロセスが置き換えられます。

+0

これを答えに書かれているような独自のコマンドを持つrubygemとどのように統合すればよいですか? –

+0

@empo最後に、rubyスクリプトは 'exec 'bash''を追加します。コマンドラインから 'exec myfoo new project'に変更してください。これはまだclunkyです:( – diedthreetimes