Bash - 带空格的可选参数

Bash - Optional argument with spaces

我有一个 bash 脚本,我想用它来将带空格的可选参数传递给另一个脚本。 我的脚本 (pass_optional_arg.sh) 看起来像:

#!/usr/bin/env bash

mandatory_arg=

if [[ -z ${mandatory_arg} ]]
then
  echo "Mandatory arg missing"
  exit 1
fi

optional_arg=

./echo_args.sh ${mandatory_arg} an_irrelevant_arg  "${optional_arg}"

脚本 echo_args.sh 仅打印单引号中的参数及其编号:

#!/usr/bin/env bash

echo "Number of args: ${#}"
for var in "${@}"
do
    echo "Arg: '"${var}"'"
done

运行宁./pass_optional_arg.sh a_mandatory_arg 'an arg with spaces'

的输出

Number of args: 3

Arg: 'a_mandatory_arg'

Arg: 'an_irrelevant_arg'

Arg: 'an arg with spaces'

这正是我想要的。 但是,如果我 运行 没有提供可选参数: ./pass_optional_arg.sh a_mandatory_arg

Number of args: 3

Arg: 'a_mandatory_arg'

Arg: 'an_irrelevant_arg'

Arg: ''

在这种情况下,我希望参数为 2,而不是末尾的空参数。

如果我更改 pass_optional_arg.sh 的最后一行以从可选 arg ./echo_args.sh ${mandatory_arg} an_irrelevant_arg ${optional_arg}

中删除引号

那么第二种情况是固定的,但第一种情况中断了: ./pass_optional_arg.sh a_mandatory_arg 'an arg with spaces'

Number of args: 6

Arg: 'a_mandatory_arg'

Arg: 'an_irrelevant_arg'

Arg: 'an'

Arg: 'arg'

Arg: 'with'

Arg: 'spaces'

当然,我可以用一个 if 语句来满足这两种情况

if [[ -z ${optional_arg} ]]
then
  ./echo_args.sh ${mandatory_arg} an_irrelevant_arg
else
  ./echo_args.sh ${mandatory_arg} an_irrelevant_arg  "${optional_arg}"
fi

这对于像这样的小命令来说可能没问题,但不能扩展为多个可选参数。同样对于非常复杂和冗长的命令,必须像这样复制它是不理想的。如果没有上述 if 语句,有什么方法可以使它工作?

我发现了几个关于可选参数或带空格的参数的问题,例如 , this and this,但我在其中找不到任何问题。

你在某处需要一个条件,因为 "..." 总是一个不同的参数,即使 ... 是空的。顺便说一下,你绝对想引用 all 参数扩展:

./echo_args.sh "${mandatory_arg}" an_irrelevant_arg "${optional_arg}"

您可能想改用数组:

mandatory_arg=

# Check $# directly; just because  is empty doesn't mean it is *missing*
if (( $# < 1 ))
then
  echo "Mandatory arg missing"
  exit 1
fi
# Or simply
# mandatory_arg=${1:?Mandatory arg missing}

args=( "$mandatory_arg" an_irrelevant_arg )
(( $# >= 2 )) && args+=("")

./echo_args.sh "${args[@]}"