Bash

從 bash 腳本執行構造的命令

  • March 9, 2019

我在 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是 string my_cmd --verbose。分詞把它分成兩個詞my_cmd--verbose。萬用字元什麼都不做,因為任何單詞中都沒有萬用字元。因此擴展產生的命令$a由兩個單詞my_cmdand組成--verbose,因此該命令my_cmd(可以是別名、函式、內置函式或 PATH 中的執行檔)使用單個參數 執行--verbose

在第二個片段中,情況相似,擴展後產生了三個詞URL=myurlmy_cmd--verbose。這導致嘗試URL=myurl使用兩個參數執行命令。

shell 命令URL=myurl my_cmd --verbose的解析方式不同:第一個單詞被解析為對變數的賦值URL,並且由於它後面有一個命令名稱,因此賦值僅在命令期間設置環境變數。這是解析的一部分,不是擴展後完成的,所以它要求等號是shell原始碼的一部分,等號不能是一些擴展的結果。

不要將帶有參數的命令儲存到字元串中。使用數組。對於復雜的命令,例如除了執行命令之外還設置變數或執行重定向的命令,如果可能,請使用函式,如果不使用eval(注意正確引用)。

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