2014-06-18 22 views
1

bash PS1變量貌似可以訪問所有shell的變量。

$ foo=bar 
$ PS1='$foo ' 
bar # Works as expected. 

但是,在那裏設置變量不起作用。

$ PS1='$(bar=baz)\$ ' 
$ echo $bar 

$ # Does not work. 

爲什麼,並如何使這項工作?

+0

shell是在顯示提示符之前解釋'PS1'的內容的過程,所以'$$'只會引用shell進程。 –

+0

@ D.Shawley如果我在'PS1'中放置'$(show-me-the-PID.sh)'這樣的腳本,'PID'每次都會改變。我說過,因爲這個行爲對我來說是意料之外的新手。 –

+0

在這種情況下,'PS1'的評估是在新的子進程中創建一個子進程並運行_show-me-the-PID.sh_。 –

回答

1

爲什麼:

PS1變量被評價爲一個字符串。在bash字符串,你可以這樣做:

$ myString="$foo" 

這:

$ myString="Date: $(date)" 

但不是這樣的:

$ myString="$(foo=bar)" 

PS1變量根本就不是從這個規則約束。

注:mkelement0在評論中解釋說,這是因爲foo=bar部分將在子shell執行,因此,你可以做$(foo=bar;echo $foo),雖然 - 它只是變量將僅在該範圍存在。

如何使這項工作:

還有另一個變量,叫PROMPT_COMMAND。在對PS1變量進行評估之前,此處的代碼將爲每個提示字符串處的eval()'d。

因此,即使只是寫你的分配這裏,是將工作:

$ PROMPT_COMMAND='bar=baz' 
$ echo $bar 
baz # Works! 

記住要檢查,如果你沒有,你可能要保持PROMPT_COMMAND覆蓋了原先設定的內容,雖然。

+1

一般來說很有幫助,但是將其預先加入到PS1變量中很令人困惑:或許你的意思是說,在顯示主提示符之前打印出'$ PROMPT_COMMAND'的_output_ - 如果有的話。至於爲什麼'$(foo = bar)'不按照你想要的方式工作:'$(...)'被稱爲命令替換,它在_subshel​​l_中運行封閉的命令,該_subshel​​l_是一個子進程,它接收當前shell環境的_copy_,但不能更改_current_ shell的環境。但請注意,變量賦值_is_有效_在子外殼內。 – mklement0

+0

謝謝@ mklement0,用你的輸入編輯了答案。 –

+0

感謝您的更新。 +1。 – mklement0