在bash中有条件地省略命令行选项

8

我有一个很长的命令,我想在某种情况下修改它以包括一个选项或不包括该选项。

例如:

java -jar compiler.jar --externs "$externs"
    --foo "another" --bar "more"

如果$externs为空,我希望完全省略--externs "$externs"。在bash中是否有不用构建整个命令字符串的方法来实现这一点?


我假设这是在脚本的上下文中? - miken32
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Chris Middleton
这个怎么样:https://dev59.com/M2Uq5IYBdhLWcg3wJM9A - EmilyR
顺便提一下,这是BashFAQ#50的子问题3:http://mywiki.wooledge.org/BashFAQ/050#I_only_want_to_pass_options_if_the_runtime_data_needs_them - Charles Duffy
1
@miken32,在我回答你的澄清请求之前,你已经删除了你的答案。请检查externs='two words'; if [ ! -z "$externs" ]; then externs_option="--externs \"$externs\""; fi; printf '%q\n' java -jar compiler.jar $externs_option --foo "two words" --bar "etc"的输出,并比较传递给--externs和传递给--footwo words - Charles Duffy
显示剩余2条评论
2个回答

11

这就是${key:+WORDS}扩展的用处:

java ... ${externs:+--externs "$externs"}

使用数组是一种常见的习语:

args=( )
if [[ $externs ]]; then
  args+=( --externs "$externs" )
fi

java ... "${args[@]}"

这个答案写得很好,我也喜欢你的数组方法。不过我认为在 + 前面缺少了一个 : - Chris Middleton
@ChrisMiddleton,是否在+之前加上:取决于您如何处理空值,而不是未设置的值;如果您想将存在但为空的变量视为未设置,则应该使用:+ - Charles Duffy
@ChrisMiddleton,...我重新阅读了您的问题,您确实明确提到了“empty”;已做出相应修改。 - Charles Duffy
使用Google的Closure Compiler,我必须为每个外部文件提供单独的“--externs”选项,因此您的数组方法在我的情况下非常有用。 - Chris Middleton

5

你可以尝试

java -jar compiler.jar ${externs:+--externs} "${externs:-}"  --foo "another" --bar "more"

说明,来自bash文档

${parameter:-word}

使用默认值。如果参数未设置或为空,则替换为单词的扩展。否则,替换为参数的值。

${parameter:+word}

使用备用值。如果参数为空或未设置,则不进行替换,否则替换为单词的扩展。

您可以尝试以下操作:

externs="some value"
printf '%s\n' ${externs:+--externs} "${externs:-}"

输出

--externs
一些值

注意:我在这里使用printf测试了$externs包含多个单词的情况,如果在变量扩展后没有应用引号,输出将如下所示:

--externs
一些

因此,我认为这应该足够了。

externs=
echo ${externs:+--externs} "${externs:-}"

输出: 空值


从正确性的角度来看,我对此没有什么可补充的——这是一个好答案(比我的更加谨慎地遵循 POSIX sh 规范,我依赖于 bash 实现但文档化不太好的行为)。话虽如此,排版有何问题呢?> 主要用于引用文本;这里可能有不同的含义。 - Charles Duffy
谢谢你的回答。我特别喜欢使用 :- 的方法。我选择了 Charles 的答案,因为它是第一个并且也提供了数组解决方案,但这里还有一些很棒的东西。通过一些实验,我发现如果 foo=,那么 ${foo:-} 将是省略的参数,而 ${foo:-""} 将是空字符串。很酷。 - Chris Middleton
酷,我认为 > 格式只是为了在代码和输出之间进行视觉区分。当然,如果你的代码是可移植的,那就更好了。 - the_velour_fog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接