我有一个用于构建内核的脚本,并且其中有一个我想用来捕获构建命令中的错误的函数,但是我不知道如何将多个参数作为一个参数来传递好好工作。语法如下:
run_build() {
cmd=$($1)
status=${PIPESTATUS[0]}
$*
if ($status != 0); then
echo "$cmd failed!"
exit 1
else
echo "$cmd succeeded."
fi
}
问题是,当我尝试传递带有参数的make
命令时,正在执行make
命令且没有参数。我试图使用“ $ *”语法来调用所有参数,但是它似乎不起作用。一个示例命令将是
make O=out -j8 zImage
从脚本中调用该行时,我需要包含接下来的3个参数。有人有主意吗?
答案 0 :(得分:1)
正确的解决方案大概是
if "$@"; then
echo "$@ succeeded" >&2
else
rc=$?
echo "$@ failed" >&2
fi
但是这似乎仍然是您用更糟糕的东西代替了完美的内置功能。</ p>
答案 1 :(得分:0)
首先,您不想将整个命令作为单个参数传递:I'm trying to put a command in a variable, but the complex cases always fail!
这是主要错误:cmd=$($1)
– $()
语法调用执行第一个参数的Command Substitution。只需使用cmd=$1
将第一个参数存储到“ cmd”变量中即可。
其他错误:
if ($status != 0); then
-语法不正确:使用if ((status != 0)); then
进行正确的算术评估。$*
-要正确执行位置参数,请使用"$@"
(带引号)-该表单将保留任何包含空格的预期参数。答案 2 :(得分:0)
由于一些明显的原因和一些不太明显的原因,不喜欢此设置。
记录下来,请c.f. this page on why not to do this。
同样值得一提的是,如果您切换到eval
,从概念上讲,这是该函数正在执行的操作……please read this too。
...但是要简化解决方案-
参数以数组形式出现。如果您正在运行构建,请使用 引用 参数使函数运行构建。
run_build() {
if make "$@" # QUOTED, *explicit* call to make
then echo "'make $@' succeeded."
else echo "'make $@' failed."
return 1 # exit in function only sets return - be explicit
fi
}
run_build O=out -j8 zImage # run_build as a make synonym
请勿尝试构建任何功能。
那就是疯狂。
如果必须使用make以外的其他命令,请进行验证。
run_build() {
local cmd=$1
shift
case "$cmd" in
make|or|some|other|specifically|ok|word)
if "$cmd" "$@" # QUOTED!!!
then echo "'$cmd $@' succeeded."
else echo "'make $@' failed."
return 1
fi
;;
*) echo "Invalid argument: '$cmd' not recognized."
return 1
;;
esac
}
如果您至少没有这样做,该函数的目的是什么?我的意思是,您无论如何都传递了命令的所有部分,除了执行它们之外,没有对它们做太多事情。为什么不只是...您知道要执行它们,而不是为函数烦恼呢?但是即使您坚持最简单的做法,也要引用,引用,引用。
run_build() { "$@" && echo "'$@' succeeded" || {
echo "'$@'failed; return 1; }; }