Bash

將參數添加到“bash -c”

  • November 18, 2018

假設我想通過 Bash 執行一個命令,如下所示:

/bin/bash -c "ls -l"

根據 Bash 手冊頁,我也可以這樣執行它:

#               don't process arguments after this one
#               |   pass all unprocessed arguments to command
#               |   |
#               V   V
/bin/bash -c ls -- -l

除了它似乎不起作用(它似乎被忽略了)。我做錯了什麼,還是我解釋手冊頁錯了?

man 的相關引用:

如果存在 -c 選項,則從字元串中讀取命令。如果字元串後面有參數,則將它們分配給位置參數,從 $0 開始。

A – 表示選項結束並禁用進一步的選項處理。– 之後的任何參數都被視為文件名和參數。

您對手冊頁的解釋是錯誤的。首先,關於--發出選項結束信號的部分與您嘗試做的事情無關。從該-c點開始覆蓋命令行的其餘部分,因此它根本不再經歷 bash 的選項處理,這意味著--將傳遞給命令,而不是由 bash 作為選項結束標記處理。

第二個錯誤是將額外的參數作為位置參數分配給啟動的 shell 程序,而不是作為參數傳遞給命令。因此,您嘗試做的事情可以作為以下之一來完成:

/bin/bash -c 'echo "$0" "$1"' foo bar
/bin/bash -c 'echo "$@"' bash foo bar

在第一種情況下,顯式傳遞參數$0和回$1顯,在第二種情況下,使用"$@"“除了 $0 之外的所有位置參數”正常擴展。請注意,在這種情況下,我們也必須傳遞一些要使用的東西$0;我選擇了“bash”,因為那是$0通常的情況,但其他任何方法都可以。

至於這樣做的原因,而不是僅僅將您直接提供的任何參數傳遞給您列出的命令:請注意,文件中說“命令從字元串中讀取的”,複數形式。換句話說,此方案允許您執行以下操作:

/bin/bash -c 'mkdir "$1"; cd "$1"; touch "$2"' bash dir file

但是,請注意,實現最初目標的更好方法可能是使用env而不是bash

/usr/bin/env -- "ls" "-l"

如果您不需要 shell 提供的任何功能,則沒有理由使用它 -env在這種情況下使用它會更快、更簡單且輸入更少。而且您不必費力地確保它能夠安全地處理包含 shell 元字元或空格的文件名。

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