![如何在不阻止空字符串删除的情况下防止分词?](https://linux22.com/image/101903/%E5%A6%82%E4%BD%95%E5%9C%A8%E4%B8%8D%E9%98%BB%E6%AD%A2%E7%A9%BA%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%88%A0%E9%99%A4%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E9%98%B2%E6%AD%A2%E5%88%86%E8%AF%8D%EF%BC%9F.png)
我需要将参数扩展作为程序参数传递。扩展结果是带有空格的文件名。因此,我用双引号将其文件名作为单个单词:"$var"
.
只要$var
包含文件名,程序就会获得一个单词参数并且可以正常工作。然而,有时扩展会产生一个空字符串,当它作为参数传递时,会破坏程序(我无法更改)。
根据 Bash 参考手册,不删除空字符串是指定的行为:
如果没有值的参数在双引号内展开,则会产生空参数并被保留。
但是,如何管理需要引用变量但也需要丢弃空字符串扩展的情况?
编辑:
感谢乔治·瓦西里乌(George Vasiliou),我发现我的问题中缺少一个细节(只是试图保持简短:))。运行程序是一个很长的java调用,缩写如下:
java -cp /etc/etc MyClass param1 param2 "$var" param4
确实,使用if
George 描述的语句可以解决问题。但这需要一次在子句中带有“$var”的调用then
和一次在else
子句中不带有“$var”的调用。
为了避免重复,我想看看是否有一种方法可以使用单个调用在“$var”为空时丢弃它的扩展。
答案1
这${parameter:+word}
参数扩展形式似乎可以完成工作
( xyz=2; set -- ${xyz:+"$xyz"}; echo $# )
1
( xyz=; set -- ${xyz:+"$xyz"}; echo $# )
0
( unset xyz; set -- ${xyz:+"$xyz"}; echo $# )
0
所以这应该翻译成
program ${var:+"$var"}
在你的情况下
答案2
在bash
具有类似数组支持的 shell 中,您可以执行以下操作:
# default is an empty array
param=()
# if $var is not empty then add it to array
[[ "$var" ]] && param=("$var")
# use the $@-like magic for arrays
java -cp /etc/etc MyClass param1 param2 "${param[@]}" param4
演示
demo() {
[[ "$var" ]] && param=("$var") || param=()
echo -n 'output: '
printf '<%s> ' before "${param[@]}" after
echo
}
demo # output: <before> <after>
var=''
demo # output: <before> <after>
var='foo bar'
demo # output: <before> <foo bar> <after>
笔记
也可以看看https://github.com/koalaman/shellcheck/wiki/SC2086#exceptions从哪里进场伊鲁瓦尔的回答也再次解释了一遍。
答案3
不清楚你想要做什么,但如果足够的话不是很简单吗?例如:
[[ ! -z "$var" ]] && call_program_with_arg "$var"
或者
if [[ ! -z "$var" ]];then call_program "$var";fi
如果 $var 为空,则什么也不会发生。如果不为空则调用你想要的程序。
问题更新后:
parameters=( "Param1" "Param2" )
[[ ! -z "$var" ]] && parameters+=( "$var" "Param4") || parameters+=( "Param4" )
java -cp /etc/etc MyClass "${parameters[@]}"
测试:
$parameters=( "Param1" "Param2" );var="my file.java";[[ ! -z "$var" ]] && parameters+=( "$var" "Param4") || parameters+=( "Param4" );echo java -cp /etc/etc MyClass "${parameters[@]}"
>java -cp /etc/etc MyClass Param1 Param2 my file.java Param4
$parameters=( "Param1" "Param2" );var="";[[ ! -z "$var" ]] && parameters+=( "$var" "Param4") || parameters+=( "Param4" );echo java -cp /etc/etc MyClass "${parameters[@]}"
>java -cp /etc/etc MyClass Param1 Param2 Param4