從 bash 腳本執行構造的命令
我在 bash 腳本中建構了這樣的命令
a="my_cmd"; a="$a --verbose"; echo $a; $a;
它可以正常工作並正確執行我的命令。但是,當我將環境變數添加到混合中時,它會中斷。
a="my_cmd"; a="URL=myurl $a --verbose"; echo $a; $a;
它在“URL = myurl”處中斷,說沒有這樣的文件或目錄,但是如果我使用 eval() 執行它,該命令可以正常工作。
a="my_cmd"; a="URL=myurl $a --verbose"; echo $a; eval "$a";
為什麼將環境變數添加到混合中會破壞我在第二個範例中的命令。
當您不引用變數擴展時,它會經歷分詞和文件名擴展(即萬用字元)。它不會被解析為 shell 命令。通常,當您動態建構要執行的 shell 片段時,執行它的正確方法是
eval "$a"
包含a
要解析為 shell 程式碼的字元串。在您的第一個程式碼段中, 的值
a
是 stringmy_cmd --verbose
。分詞把它分成兩個詞my_cmd
和--verbose
。萬用字元什麼都不做,因為任何單詞中都沒有萬用字元。因此擴展產生的命令$a
由兩個單詞my_cmd
and組成--verbose
,因此該命令my_cmd
(可以是別名、函式、內置函式或 PATH 中的執行檔)使用單個參數 執行--verbose
。在第二個片段中,情況相似,擴展後產生了三個詞
URL=myurl
:my_cmd
和--verbose
。這導致嘗試URL=myurl
使用兩個參數執行命令。shell 命令
URL=myurl my_cmd --verbose
的解析方式不同:第一個單詞被解析為對變數的賦值URL
,並且由於它後面有一個命令名稱,因此賦值僅在命令期間設置環境變數。這是解析的一部分,不是擴展後完成的,所以它要求等號是shell原始碼的一部分,等號不能是一些擴展的結果。不要將帶有參數的命令儲存到字元串中。使用數組。對於復雜的命令,例如除了執行命令之外還設置變數或執行重定向的命令,如果可能,請使用函式,如果不使用
eval
(注意正確引用)。