尝试在脚本中使用 zenity 中的空格时出现问题

尝试在脚本中使用 zenity 中的空格时出现问题

虽然这是直接在终端中执行的,但效果很好

zenity --info --text "pure info" --title "get info"

但是这个脚本不起作用,这是怎么回事?

!/bin/bash
ZEN="--info --text \"pure info\" --title \"get info\""
zenity $ZEN

该脚本输出如下:“文本中的信息和标题中的”jeevan。它正在跳过剩余的部分。
是因为双引号内的空格(特殊字符)失去了它的特殊含义吗?

答案1

不同之处在于,该命令zenity在第一种情况下看到多个参数,而在第二种情况下仅看到一个参数(包括大量空格)。

使用以下awk程序,您可以快速输出 shell 将参数扩展为的内容。碰巧,zsh我可以重现您的问题:

% awk 'BEGIN {for (i in ARGV) print "ARGV["i"] =", ARGV[i]}' $ZEN                                               
ARGV[0] = awk
ARGV[1] = --info --text "pure info" --title "get info"

bash它看起来几乎就像它应该看起来的那样(请注意,引用的字符串被分成单词):

$ awk 'BEGIN {for (i in ARGV) print "ARGV["i"] =", ARGV[i]}' $ZEN
ARGV[0] = awk
ARGV[1] = --info
ARGV[2] = --text
ARGV[3] = "pure
ARGV[4] = info"
ARGV[5] = --title
ARGV[6] = "get
ARGV[7] = info"

应该有一个 shell 分词选项来负责这种行为。

然而,这有效:

set -- --info --text "pure info" --title "get info"
zenity "$@"

编辑:

默认情况下,Shell 的分词功能有点愚蠢,请参阅bash上面示例中的行为:"pureandinfo"是两个单独的单词。由于这在解析命令行选项时很烦人,因此在处理"$@.引用bash手册,特殊参数部分:

   @      Expands  to  the positional parameters, starting from one.  When
          the  expansion  occurs  within  double  quotes,  each  parameter
          expands to a separate word.  That is, "$@" is equivalent to "$1"
          "$2" ...

我还没有找到一种方法来$@对正常变量扩展进行特殊处理,但可能有一个技巧。

set命令设置位置参数 , $1, $2...。因此,“Give me all”版本的位置参数 , $@, 也可用。

答案2

解决此问题的一种方法是eval计算整个表达式,以便解析字符串内的引号:

eval zenity "$ZEN"

顺便说一句,您还可以在变量定义中使用单引号而不是转义双引号:

ZEN='--info --text "pure info" --title "get info"'

#顺便说一句,你前面缺少!/bin/bash.

如果您使用 zsh,则另一种方法是使用带有标志的 shell 解析(考虑引用)将参数拆分为单词z,即:

zenity "${(z)ZEN}"

相关内容