2014-06-06 117 views
3

當執行IO.popenexec時,Ruby從哪裏拾取默認的PATH變量?Ruby popen和可執行文件路徑?

例如在zsh中:

echo $PATH 
/Users/bibstha/.rubies/ruby-2.1.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin 

這證實到ENV['PATH']在IRB:

irb(main):026:0> ENV['PATH'] 
=> "/Users/bibstha/.rubies/ruby-2.1.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" 

,但不與popen

irb(main):024:0> IO.popen("echo $PATH").read.chomp 
=> "/usr/bin:/bin:/usr/sbin:/sbin" 

更新

我已經嘗試過與OSX Yosemite(10.10)發佈的ruby以及使用ruby-install進行自定義安裝。

Homebrew在/ usr/local/bin中安裝了很多應用程序,由於ruby在PATH中沒有這個,所以我的兩個腳本都失敗了。

+1

我正在使用rbenv和IO.popen(「echo $ PATH」)。read.chomp和ENV ['PATH']完全相同,但shell中的echo $ PATH不同。 – archie

+0

如果使用.bashrc或.zshrc更新$ PATH,它是否會被IO.popen(「echo $ PATH」)拾取? – bibstha

回答

1

發現此問題。顯然ENV不是一個哈希,而是一個對象。

我有兩個PATH所以ENV有兩個鍵與PATH(我不知道這是可能的)。 刪除了最後一個PATH變量,現在看起來工作正常。

2

它從你給它的環境的路徑,所以給它一個:

IO.popen(ENV, "echo $PATH").read.chomp 

new_env = {'PATH' => '/path/to/foo'} 
IO.popen(new_env, "echo $PATH").read.chomp 

例如:

IO.popen({'PATH' => 'foo'},"echo $PATH").read.chomp 
# => "foo" 

這是第一個參數在the documentation

popen([env,] cmd, mode="r" [, opt]) → io 
popen([env,] cmd, mode="r" [, opt]) {|io| block } → obj 

它沒有明確規定,但是這是什麼意思呢:

陣列可包含第一對環境的哈希和哈希終於類似產卵選項。

如果您不傳遞環境信息,Ruby將使用傳遞給它的默認ENV散列來創建一個環境。我將這看作是一種安全選擇,允許您限制訪問權限,或更改被調用代碼的環境信息。

=> "/usr/bin:/bin:/usr/sbin:/sbin" 

看起來像根用戶所看到的。通常root運行的路徑非常有限。

+0

這是OSX中的普通用戶帳戶。我也更新了這個問題。我不明白答案的安全部分。你能詳細說明一下嗎? – bibstha