如何将带有参数作为单个参数的命令传递给脚本?

时间:2019-02-19 14:35:33

标签: bash variables pipe command-line-arguments

我有一个用于构建内核的脚本,并且其中有一个我想用来捕获构建命令中的错误的函数,但是我不知道如何将多个参数作为一个参数来传递好好工作。语法如下:

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个参数。有人有主意吗?

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; }; }