Bash
使用變數中字元串中的命令替換 bash 命令的行為
$ echo $(echo x; echo y) x y $ a='echo x; echo y' $ echo $($a) # expect 'x y' x; echo y
- 為什麼命令替換會以這種方式表現?
eval
如何在不使用and的情況下對儲存在變數中的命令列表執行命令替換bash -c
?
echo $(eval $a)
並且echo $(bash -c "$a")
實際上做了我想要的,但我聽說使用 eval 經常是解決問題的錯誤方法,所以我想知道如何在沒有這些命令的情況下進行管理(bash -c
實際上使用是同一件事)
分詞發生在命令評估的後期。對您來說最關鍵的是,它發生在變數擴展和命令替換之後。
這意味著第二行
s="echo a; echo b" echo $($s)
將首先
$s
擴展為echo a; echo b
然後執行該命令,而不將其拆分為由兩個echo
s 組成的複合命令。(細節:
$s
被分成四個詞,,,echo
和a;
。封裝將echo
其作為一個命令執行,帶有三個參數,,和,即,你基本上有)。b``$(...)``echo``a;``echo``b``echo $('echo' 'a;' 'echo' 'b')
因此,給 outmost
echo
的是字元串a; echo b
(實際上是三個單詞,$(...)
不在引號中),因為這是 innermost 輸出的echo
。比較一下
s1="echo a" s2="echo b" echo $($s1;$s2)
這會產生您所期望的結果。
是的,“
eval
是邪惡的”,大多數時候,sh -c
如果你不知道自己在做什麼,可能會感到笨拙和脆弱。但是假設您有一些 shell 程式碼,您信任shell 腳本中的字元串。在這種情況下,這些工具是使程式碼正確執行的唯一(?)方法,因為這通常需要將字元串中的文本顯式評估為 shell 程式碼(從開始到結束的所有評估階段),特別是如果它是複合命令。我認為這只是由於 Unix shell 與文本的密切關係,您有幸
echo $($s)
執行了某些操作。想想你必須採取的步驟來讓 C 程序執行一段 C 程式碼,該程式碼以字元串形式給出……