“failed to avoid ‘[: too many arguments'”

huangapple go评论59阅读模式
英文:

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/Quoteshttp://mywiki.wooledge.org/Argumentshttp://wiki.bash-hackers.org/syntax/words何时需要双引号

bash中,最好使用这种形式,无需引用:

MyVar="a b" ; [[ $MyVar == "a b" ]]

[[是一个类似于(但更强大的)[命令的bash关键字。请参阅:http://mywiki.wooledge.org/BashFAQ/031http://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=&quot;a b&quot; ; [[ $MyVar == &quot;a b&quot; ]]

[[ 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=&quot;a b&quot; ; [ &quot;$MyVar&quot; = &quot;a b&quot; ] &amp;&amp; echo ok

Note the use of single = operator mandatory for POSIX shell.

答案2

得分: 1

  • 为什么我的方法无效。

这是因为不加引号的 $MyVar 会分成
"ab"(两个字符串),而 == 运算符只在左侧有一个参数和右侧有一个参数时起作用。

请注意,参数扩展是一次性的。它将变量 $MyVar 扩展为 "ab",然后不会重新评估结果。扩展发生的顺序列在Shell扩展中:

  • 扩展的顺序是:大括号扩展;波浪号扩展,参数和变量扩展,算术扩展和命令替换(从左到右进行);单词分割;和文件名扩展。
英文:

> why is my approach ineffective.

That's because $MyVar without quotes will be split into
&quot;a and b&quot; (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 &quot;a and b&quot; 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.

huangapple
  • 本文由 发表于 2023年5月8日 01:54:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195452.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定