Bash

使用變數中字元串中的命令替換 bash 命令的行為

  • February 5, 2022
$ echo $(echo x; echo y)
x y
$ a='echo x; echo y'
$ echo $($a)  # expect 'x y'
x; echo y
  1. 為什麼命令替換會以這種方式表現?
  2. 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然後執行該命令,而不將其拆分為由兩個echos 組成的複合命令。

(細節:$s 被分成四個詞,,,echoa;。封裝將echo其作為一個命令執行,帶有三個參數,,和,即,你基本上有)。b``$(...)``echo``a;``echo``b``echo $('echo' 'a;' 'echo' 'b')

因此,給 outmostecho的是字元串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 程式碼,該程式碼以字元串形式給出……

引用自:https://unix.stackexchange.com/questions/388345