[英]Escaping bash function arguments for use by su -c
我希望能夠編寫一個函數su_mt_user
(當前)看起來像這樣:
su_mt_user() {
su someuser -c "$*"
}
目標是能夠像這樣使用它:
su_mt_user mt-auth --stuff etc
哪個將以用戶someuser
運行命令mt-auth --stuff etc
。 當前版本適用於此特定命令,但對於以下命令失敗:
some_filename_with_spaces="/home/user/hello there i like spaces in filenames.txt"
su_mt_user stat "$some_filename_with_spaces"
此操作失敗,並出現以下錯誤:
stat: cannot stat '/home/user/hello': No such file or directory
stat: cannot stat 'there': No such file or directory
stat: cannot stat 'i': No such file or directory
stat: cannot stat 'like': No such file or directory
stat: cannot stat 'spaces': No such file or directory
stat: cannot stat 'in': No such file or directory
stat: cannot stat 'filenames.txt': No such file or directory
我假設發生此錯誤是因為即使$some_filename_with_spaces
作為一個參數正確傳遞給su_mt_user
函數,該函數su_mt_user
將其擴展為帶有"$*"
多個參數。
我也試過這個,試錯了:
su_mt_user() {
su someuser -c "$0 $@"
}
但那也失敗了( /usr/bin/stat: cannot execute binary file
(什么?))
當然, stat "$some_filename_with_spaces"
可以從當前用戶和someuser
用戶按預期工作。
這看起來像是需要做一些逃避,但是bash知道如何做到這一點嗎? 是否需要手動替代? 如果是這樣,哪些角色需要轉義?
要通過函數將多個參數傳遞給命令,需要"$@"
。 "$@"
的特殊之處在於即使它在雙引號之間,單獨的參數也以不同的詞結尾,所以它們完全按原樣傳遞。 這與帶有引號的$@
或$*
不同,后者會將每個參數拆分為包含空格並將每個結果單詞解釋為glob模式,並從"$*"
中將所有參數合並為一個帶有空格的單個參數。之間。
還有一個額外的皺紋,因為su
不直接吃掉論點,它們通過一個shell。 su
的非選項參數作為參數傳遞給sh -c
,然后您需要為-c
提供適當的命令。
su_mt_user() {
su someuser -c '"$0" "$@"' -- "$@"
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.