2016-05-23 33 views
1

私が持っている:Rubyスクリプトでbashプロンプトにアクセスできないのはなぜですか?私<code>.bash_profile</code>で

if [ -f $(brew --prefix)/etc/bash_completion ]; then 
    source $(brew --prefix)/etc/bash_completion 
    GIT_PS1_SHOWDIRTYSTATE=1 
    git_prompt='$(__git_ps1)' 
fi 
export PS1="\[\e[33m\] \d \t \w$git_prompt\n\[\e[m\]\\$ " 
export MYTESTVAR="hello world" 

私が含まれているRubyスクリプトfoo.rbを持っている:

`source ~/.bash_profile` 
puts `printenv` 
puts `echo $PS1` 
puts `echo $MYTESTVAR` 

私はruby foo.rbprintenvコマンドリストのすべての環境変数を実行し、$MYTESTVARラインが正しくhello worldを返します。 。

ただし、$PS1は表示されません。どうしてこれなの?

答えて

3

$ MYTESTVAR行が正しくhello worldを返します。 $ PS1が表示されません。

実際、あなたは正しいです。ほとんどの変数が正常に動作しますが、特に "PS1は" 失敗:

$ PS1=ps1 TEST1=test1 ruby -e 'puts `echo $PS1 and $TEST1`' 
and test1 

これはなぜですか? Cであなたがexecl("/bin/sh", "-c", somestring, NULL)へのパイプを開いていたかのようにRubyで

、あなたはおそらく認識しているとして、`somestring`は、シェルでsomestringを実行します。

多くのシステムでは、/bin/shbashで提供されています。バッシュはits initialization codeにこのスニペットを持っています

つまり
/* Execute the start-up scripts. */ 

    if (interactive_shell == 0) 
    { 
     unbind_variable ("PS1"); 
     unbind_variable ("PS2"); 
     interactive = 0; 

これらの変数は唯一のインタラクティブシェルで使用するために意図されているので、それが明示的に「PS1」と「PS2」を削除します。

/bin/bashは、あなたが代わりにあなたが期待される結果を得るために多くの近代的なDebianベースのディストリビューションのデフォルトとして、 dashによって提供され、他のシステムでは

$ PS1=ps1 TEST1=test1 ruby -e 'puts `echo $PS1 $TEST1`' 
ps1 and test1 

あなた`source ~/.bash_profile`が、これは修正されない理由各`backtick command`は別のシェルで実行されます。ある変数に設定された変数は、他の変数に反映されません。

あなたのシェルによってエクスポートされた変数だけを使用したい場合は、@anujmが示唆していることを実行してENV['PS1']で直接取得する必要があります。これは簡単で堅牢なだけでなく、1000倍も高速です。

あなた.bash_profileにセットとして変数をしたい場合は、関係なく、あなたのスクリプトを実行したかの、あなたは同じシェルでソーシングと印刷の両方を行うことができます。

puts `bash -c 'source ~/.bash_profile; printf "%s" "$PS1"'` 
+1

しかし、それは理由はそこよりも複雑です5つの別々のプロセスが関与し、それぞれに独自の環境があります。 –

+0

私はその部分をキャッチしませんでした。更新しました。 –

関連する問題