假設一個函式在另一個目錄中運行命令:
sub() {
cd subdirectory
eval "$@" || exit
}
我希望能夠使用在子目錄中展開的引數來呼叫此函式,例如sub ls '$(basename $(pwd))'
但是,正如上面定義的函式,它沒有通過 shellcheck:
^-- SC2294 (warning): eval negates the benefit of arrays. Drop eval to preserve whitespace/symbols (or eval as string).
顯然,如果我洗掉了 eval,那么引數不會被展開,如果我也洗掉引號,那么引數會在當前目錄中展開。這不是我想要的。
我知道 shellcheck 的 wiki 中有一些建議,但我不知道如何使它們起作用。
在這種情況下是否可以正確使用 eval - 沒有SC2294中描述的缺點- 還是我需要忽略此規則?
uj5u.com熱心網友回復:
使用eval "$*"而不是eval "$@". 這將產生完全相同的效果(假設它IFS具有其默認值)并且Shellcheck對此感到滿意。有關vs (帶引號和不帶引號)的詳細資訊,請參閱訪問 bash 命令列引數 $@ vs $* 。$@$*
eval通常不鼓勵使用 ,這是有道理的。請參閱為什么在 Bash 中應避免使用 eval,而我應該使用什么?. 但有時沒有更好的選擇。
uj5u.com熱心網友回復:
...洗掉評估...
所以放下它。
sub() {
cd subdirectory
"$@" || exit
# I would do:
if ! "$@"; then
exit
fi
}
sub sh -c 'ls "$(basename "$(pwd)")"'
使用在子目錄中展開的引數呼叫此函式
使用eval是邪惡的。考慮一種不同的方法 - 使用將要執行的代碼定義一個函式。
todo() {
# properly escaped script
ls "$(basename "$(pwd)")"
}
sub todo
而且,總體而言,如果這是用于互動式使用,并且您知道自己在做什么以及 的問題eval,請留下它并消除警告。例如,監視引數通過 運行sh,例如watch 'echo $(date)'.
sub() {
cd subdirectory
sh -c "$*"
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/474241.html
下一篇:如何合并兩個JSON陣列變數?
