英文:
failed to avoid “[: too many arguments”
问题
I know that MyVar="a b" ; [ $MyVar = "a b" ] will signal an error because the resultant expansion is [ a b = "a b" ].
I tried to avoid that case:
$ MyVar="\"a b\""
$ [ $MyVar = "a b" ]
-bash: [: too many arguments
Why did I fail? Didn't it expand to [ "a b" = "a b" ]?
I know there is a [[ ... ]] form; I know I can write "$MyVar".
I am asking why is my approach ineffective?
英文:
I know that MyVar="a b" ; [ $MyVar = "a b" ] will signal an error because the resultant expansion is [ a b = "a b" ].
I tried to avoid that case:
$ MyVar="\"a b\""
$ [ $MyVar = "a b" ]
-bash: [: too many arguments
Why did I fail? Didn't it expand to [ "a b" = "a b" ]?
I know there is a [[ ... ]] form; I know I can write "$MyVar".
I am asking why is my approach ineffective.
答案1
得分: 1
Sure, here's the translated content:
这是因为您遇到了Shell的单词分割:您忘记了对变量进行"引用"。
学习如何在Shell中正确引用非常重要:
对包含空格/元字符和每次扩展的每个字面量都要使用"双引号":
"$var","$(command "$var")","${array[@]}","a & b"。对于代码或字面量$'s,请使用'单引号':'Costs $5 US',ssh host 'echo "$HOSTNAME"'。请查看以下链接以获取更多信息:http://mywiki.wooledge.org/Quotes,http://mywiki.wooledge.org/Arguments,http://wiki.bash-hackers.org/syntax/words,何时需要双引号
在bash中,最好使用这种形式,无需引用:
MyVar="a b" ; [[ $MyVar == "a b" ]]
[[是一个类似于(但更强大的)[命令的bash关键字。请参阅:http://mywiki.wooledge.org/BashFAQ/031和http://mywiki.wooledge.org/BashGuide/TestsAndConditionals。除非您正在编写POSIX sh代码,否则我建议使用[[。
如果您需要编写POSIX代码,您需要使用引号:
MyVar="a b" ; [ "$MyVar" = "a b" ] && echo ok
请注意,对于POSIX shell,必须使用单个=运算符。
英文:
It's because you encounter shell word splitting: you missed to "quote" the variable.
Learn how to quote properly in shell, it's very important :
> "Double quote" every literal that contains spaces/metacharacters and every expansion: "$var", "$(command "$var")", "${array[@]}", "a & b". Use 'single quotes' for code or literal $'s: 'Costs $5 US', ssh host 'echo "$HOSTNAME"'. See
<http://mywiki.wooledge.org/Quotes>
<http://mywiki.wooledge.org/Arguments>
<http://wiki.bash-hackers.org/syntax/words>
when-is-double-quoting-necessary
Better use this form in bash, no need to quote:
MyVar="a b" ; [[ $MyVar == "a b" ]]
[[ is a bash keyword similar to (but more powerful than) the [ command. See <http://mywiki.wooledge.org/BashFAQ/031> and <http://mywiki.wooledge.org/BashGuide/TestsAndConditionals>. Unless you're writing for POSIX sh, I recommend [[
If you need to write POSIX code, you need quotes:
MyVar="a b" ; [ "$MyVar" = "a b" ] && echo ok
Note the use of single = operator mandatory for POSIX shell.
答案2
得分: 1
- 为什么我的方法无效。
这是因为不加引号的 $MyVar 会分成
"a 和 b"(两个字符串),而 == 运算符只在左侧有一个参数和右侧有一个参数时起作用。
请注意,参数扩展是一次性的。它将变量 $MyVar 扩展为 "a 和 b",然后不会重新评估结果。扩展发生的顺序列在Shell扩展中:
- 扩展的顺序是:大括号扩展;波浪号扩展,参数和变量扩展,算术扩展和命令替换(从左到右进行);单词分割;和文件名扩展。
英文:
> why is my approach ineffective.
That's because $MyVar without quotes will be split into
"a and b" (two strings) and the == operator only works with one argument on the left hand side and one argument on the right hand side.
Note that parameter expansion is a one-pass thing. It expands the variable $MyVar into "a and b" and does then not reevaluate the result. The order in which the expansions occur is listed in Shell expansion:
> The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论