如何在函数内扩展 bash 函数参数/修复 shellcheck SC2294
how to expand bash function parameters inside function / fix shellcheck SC2294
假设一个函数在另一个目录中运行命令:
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 中描述的缺点 —— 还是我需要忽略这条规则?
使用 eval "$*"
而不是 eval "$@"
。这将具有完全相同的效果(假设 IFS
具有其默认值)和 Shellcheck is happy with it. See Accessing bash command line args $@ vs $* 对于 $@
与 $*
(引用和未引用)的详细信息。
通常不鼓励使用 eval
是有道理的。参见 Why should eval be avoided in Bash, and what should I use instead?。不过有时也没有更好的选择。
... Drop eval ...
所以放弃吧。
sub() {
cd subdirectory
"$@" || exit
# I would do:
if ! "$@"; then
exit
fi
}
sub sh -c 'ls "$(basename "$(pwd)")"'
invoke this function with parameters that are expanded inside the subdirectory
使用eval
是邪恶的。考虑一种不同的方法 - 使用将要执行的代码定义一个函数。
todo() {
# properly escaped script
ls "$(basename "$(pwd)")"
}
sub todo
而且,总的来说,如果这是为了交互式使用,并且您知道自己在做什么以及 eval
的问题,就不要管它并消除警告。例如,watch 参数是 运行 via sh
,比如 watch 'echo $(date)'
.
sub() {
cd subdirectory
sh -c "$*"
}
假设一个函数在另一个目录中运行命令:
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 中描述的缺点 —— 还是我需要忽略这条规则?
使用 eval "$*"
而不是 eval "$@"
。这将具有完全相同的效果(假设 IFS
具有其默认值)和 Shellcheck is happy with it. See Accessing bash command line args $@ vs $* 对于 $@
与 $*
(引用和未引用)的详细信息。
通常不鼓励使用 eval
是有道理的。参见 Why should eval be avoided in Bash, and what should I use instead?。不过有时也没有更好的选择。
... Drop eval ...
所以放弃吧。
sub() {
cd subdirectory
"$@" || exit
# I would do:
if ! "$@"; then
exit
fi
}
sub sh -c 'ls "$(basename "$(pwd)")"'
invoke this function with parameters that are expanded inside the subdirectory
使用eval
是邪恶的。考虑一种不同的方法 - 使用将要执行的代码定义一个函数。
todo() {
# properly escaped script
ls "$(basename "$(pwd)")"
}
sub todo
而且,总的来说,如果这是为了交互式使用,并且您知道自己在做什么以及 eval
的问题,就不要管它并消除警告。例如,watch 参数是 运行 via sh
,比如 watch 'echo $(date)'
.
sub() {
cd subdirectory
sh -c "$*"
}