为什么--text =“ $ @”仅传递第一个单词?


9

当我运行带有某些参数的以下脚本时arg1 arg2 arg3

#!/bin/bash
zenity --entry --text="$@"

zenity使用以下文本创建一个输入对话框:“ arg1”,而我期望“ arg1 arg2 arg3”

如果我使用像以下脚本这样的变量,它将显示条目文本的所有参数。

#!/bin/bash
text="$@"
zenity --entry --text="$text"

这些脚本之间有什么区别?为什么第一个$@仅替换为第一个参数?

Answers:


16

$@$*bash手册中所述,扩展为单独的单词(而扩展为单个单词)。因此,当你写

zenity --text="$@"

它扩展到

zenity --text="$1" "$2" "$3"

但是,shell变量分配不会进行单词拆分。请注意,bash手册中变量分配的扩展列表中省略了字段/单词拆分。此行为与POSIX规范一致。所以,当你写

text="$@"

变量text将所有位置参数作为一个单词获取,等同于您编写了text="$*"。确实,这就是在变量分配中经常不需要双引号的原因。都

text=$@

text=$*

非常安全。

所以,

text=$@
zenity --option="$text"

扩展"$text"为一个单词,这就是为什么它起作用的原因。请注意,--option="$@"只是命令的常规参数zenity,而不是shell变量赋值,这就是为什么在此处而不是in中进行单词拆分的原因text=$@


1
+1。这也将起作用:zenity --text="$*"- "$*"扩展为单个单词。
glenn jackman 2012年

+1教给我一件事:男人!=文档。我应该搜索过信息bash,它还包含您链接到的手册部分。
manatwork,2012年

7

$@ 将每个参数扩展成单独的单词,成为

zenity --entry --text="arg1" "arg2" "arg3" # syntactically wrong for zenity

使用$*,而不是扩大它在一个单一的词

zenity --entry --text="$*"

这将成为

zenity --entry --text="arg1 arg2 arg3" # syntactically correct for zenity

请阐明为什么OP的问题中的$ text变
体会

@ChandraRavoori,你抓住了我。根据手册“不执行单词拆分,“ $ @”除外”和“如果单词中出现双引号扩展,则第一个参数的扩展将与原始单词的开头部分结合在一起, ,最后一个参数的扩展与原始单词的最后部分结合在一起。”,因此我希望text="$@"将其扩展为text="arg1" "arg2" "arg3",这会失败。但是肯定不是这样。
manatwork,2012年

@ChandraRavoori原因是变量分配中不会发生字段拆分。我在回答中会更详细地解释。
jw013 2012年

@ jw013:但是根据Bash参考手册即使在变量分配中,"$@" 也确实会进行单词拆分。
ruakh

据我所知,bash手册没有这么说。你有报价吗?
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.