虽然这是直接在终端中执行的,但效果很好
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
上面示例中的行为:"pure
andinfo"
是两个单独的单词。由于这在解析命令行选项时很烦人,因此在处理"$@
.引用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}"