簡體   English   中英

轉義bash函數參數以供su -c使用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM