如何将可选参数传递给bash脚本中的另一个命令?

And*_*rew 5 bash shell

我正在编写一个bash脚本,它接受一些可选参数.我想翻译它们并将它们传递给另一个脚本.但是,我很难优雅地传递可选参数.

这是我设法在伪代码中工作的概述:

灰:

if arg1 in arguments; then
    firstArg="first argument"
fi
if arg2 in arguments; then
    secondArg="second argument"
fi

./b.sh $firstArg $secondArg "default argument"
Run Code Online (Sandbox Code Playgroud)

请注意参数中的空格.

b.sh:

for arg in "$@"
do
    echo $arg
done
Run Code Online (Sandbox Code Playgroud)

我想调用b.sh,可选地带firstArgsecondArg和一个默认参数,如下所示:

./b.sh $firstArg $secondArg "default argument"
Run Code Online (Sandbox Code Playgroud)

这个问题是,如果$firstArg或是$secondArg带空格的字符串,它们将表示为多个参数,输出将类似于:

first
argument
second
argument
default argument
Run Code Online (Sandbox Code Playgroud)

好的,这很容易修复,让我们通过在它周围添加引号来捕获整个参数字符串,如下所示:

./b.sh "$firstArg" "$secondArg" "defaultArg"
Run Code Online (Sandbox Code Playgroud)

问题是,例如,如果firstArg没有设置,它会产生一个空行(因为它将被解释""为参数),所以输出将是这样的:

(blank line here)
second argument
defaultArg
Run Code Online (Sandbox Code Playgroud)

我也尝试构造一个字符串并将其传递给shell脚本,但它似乎也没有那样工作(它将整个字符串解释为参数,即使我将参数与引号分开).

请注意,b.sh使用引用的参数从我的命令行调用工作正常.有没有办法在bash脚本中模仿它的工作原理?

Cha*_*ffy 7

如果你真的想复制给定的所有参数,但又添加一个:

# this works in any POSIX shell
./b.sh "$@" defaultArg
Run Code Online (Sandbox Code Playgroud)

另外,要明确地传递firstArgsecondArg,但只如果存在的话(注意:被设置到一个空值计为"现有"这里):

# this works in any POSIX shell
./b.sh ${firstArg+"$firstArg"} ${secondArg+"$secondArg"} defaultArg
Run Code Online (Sandbox Code Playgroud)

如果要将set-to-empty-value视为不存在:

# this works in any POSIX shell
./b.sh ${firstArg:+"$firstArg"} ${secondArg:+"$secondArg"} defaultArg
Run Code Online (Sandbox Code Playgroud)

另一种方法是建立一个参数数组:

# this requires bash or another shell with arrays and append syntax
# be sure any script using this starts with #!/bin/bash
b_args=( )
[[ $firstArg ]] && b_args+=( "$firstArg" )
[[ $secondArg ]] && b_args+=( "$secondArg" )
b_args+=( "default argument" )
./b.sh "${b_args[@]}"
Run Code Online (Sandbox Code Playgroud)

如果您想要与数组方法具有相同灵活性的东西,但没有兼容性问题,请定义一个函数; 在其中,您可以安全地覆盖"$@"而不会影响脚本的其余部分:

runB() {
  set --
  [ -n "$firstArg" ]  && set -- "$@" "$firstArg"
  [ -n "$secondArg" ] && set -- "$@" "$secondArg"
  ./b.sh "$@" "default argument"
}
Run Code Online (Sandbox Code Playgroud)