如何在Bash命令行中仅当变量已设置时将其作为单个参数传递?
问题:Bash命令中条件传递带空格的变量参数
我需要执行一条Bash命令,要求仅当某个变量已设置时,才将该变量作为命令行参数传入;并且如果变量包含空格,必须作为单个参数传递。
下面的写法有问题:当FOO未设置或为空时,会给bar传递一个空参数:
FOO="" bar "$FOO"
下面的写法解决了空变量的问题,但变量含空格时会被拆分成多个参数:
FOO="one two" bar $FOO
我试过bar ${FOO+"}$FOO${FOO+"},虽然加了引号,但还是会拆成两个参数。用eval配合复杂引号处理应该也能行,但得反复测试才能确保正确。
当然也可以写if [ "$Z" ]; then bar "$Z"; else bar; fi,但这种写法扩展性太差,变量多了根本没法用。
请问实现这个需求的最佳方式是什么?
最佳解决方案:利用Bash的参数展开特性
直接使用带冒号的参数展开语法就能完美解决这个问题:
bar ${FOO:+"$FOO"}
语法解释:
${VAR:+"VALUE"}:当变量VAR已设置且不为空时,展开为VALUE;否则什么都不生成,不会传递空参数。- 这里用
"$FOO"作为展开值,确保变量含空格时会被当作单个参数传递。
扩展到多个变量的情况
如果需要处理多个变量,直接追加即可,扩展性拉满:
bar ${FOO:+"$FOO"} ${BAR:+"$BAR"} ${BAZ:+"$BAZ"}
特殊情况:允许传递空参数
如果你需要的是只要变量已设置(哪怕是空值)就传递空参数,去掉冒号即可:
# 当FOO=""时,会传递一个空参数给bar bar ${FOO+"$FOO"}
为什么之前的尝试失败?
你之前写的${FOO+"}$FOO${FOO+"}是把引号作为字符串的一部分,而不是Shell的语法引号,所以Shell仍然会按照空格拆分参数,自然达不到预期效果。
内容的提问来源于stack exchange,提问作者Seth Robertson
相关产品推荐
相关产品推荐

