Bash
將參數添加到“bash -c”
假設我想通過 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 元字元或空格的文件名。