英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论