如何在不阻止空字符串删除的情况下防止分词?

如何在不阻止空字符串删除的情况下防止分词?

我需要将参数扩展作为程序参数传递。扩展结果是带有空格的文件名。因此,我用双引号将其文件名作为单个单词:"$var".

只要$var包含文件名,程序就会获得一个单词参数并且可以正常工作。然而,有时扩展会产生一个空字符串,当它作为参数传递时,会破坏程序(我无法更改)。

根据 Bash 参考手册,不删除空字符串是指定的行为:

如果没有值的参数在双引号内展开,则会产生空参数并被保留。

但是,如何管理需要引用变量但也需要丢弃空字符串扩展的情况?

编辑:

感谢乔治·瓦西里乌(George Vasiliou),我发现我的问题中缺少一个细节(只是试图保持简短:))。运行程序是一个很长的java调用,缩写如下:

java -cp /etc/etc MyClass param1 param2 "$var" param4

确实,使用ifGeorge 描述的语句可以解决问题。但这需要一次在子句中带有“$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 

相关内容