Linux

/bin/sh:變數和直接命令的區別

  • July 14, 2014

想像一下我有以下 bash 腳本:

#/bin/sh
#next line will work correctly, outputting user name and current directory
start-stop-daemon --start --exec /bin/su -- root -c 'whoami; ls'

MYVAR="start-stop-daemon --start --exec /bin/su -- root -c 'whoami; ls'"
#next line will fail with following error:
#ls': -c: line 0: unexpected EOF while looking for matching `''
$MYVAR

問題 - 為什麼通過變數的第二種方法不起作用?如何讓它發揮作用?

正如@lled 解釋的那樣,問題在於shell 在擴展變數之前處理引號,因此將引號放在變數中沒有任何用處。但是有幾種選擇,具體取決於您要儲存命令的原因(而不是直接執行它)。

如果您只想定義一次命令,然後重複使用它,請使用一個函式:

myfunc() {
   start-stop-daemon --start --exec /bin/su -- root -c 'whoami; ls'
}
# ...
myfunc

如果您需要在一個地方建構/選擇命令,然後在另一個地方使用它,您可以使用 bash 數組來儲存它。將命令的每個“單詞”儲存為數組元素,然後如果您正確引用它,這些單詞中斷將被保留:

myarray=(start-stop-daemon --start --exec /bin/su -- root -c 'whoami; ls')
# ...
"${myarray[@]}"

這裡發生的是數組被定義為具有元素“start-stop-daemon”、“–start”、“–exec”、“/bin/su”、“–”、“root”、“ -c”和“whoami;ls”。單引號不儲存為數組的一部分,但它們具有使“whoami;ls”成為單個數組元素的效果。然後,在數組的擴展中,[@]告訴 shell 將每個數組元素擴展為一個單獨的單詞,並且它周圍的雙引號防止對結果值進行任何額外的單詞拆分。

有關更多資訊(以及其他幾個選項),請參閱BashFAQ #50:我正在嘗試將命令放入變數中,但複雜的情況總是失敗!

引用自:https://serverfault.com/questions/612232