bash 来自 if [] 的“[: too many arguments”错误的含义(方括号)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13781216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:04:53  来源:igfitidea点击:

Meaning of "[: too many arguments" error from if [] (square brackets)

bashif-statementarguments

提问by user56reinstatemonica8

I couldn't find any one simple straightforward resource spelling out the meaning of and fix for the following BASH shell error, so I'm posting what I found after researching it.

我找不到任何简单直接的资源来说明以下 BASH shell 错误的含义并修复它,因此我将在研究后发布我发现的内容。

The error:

错误:

-bash: [: too many arguments

Google-friendly version:bash open square bracket colon too many arguments.

谷歌友好版本:bash open square bracket colon too many arguments.

Context:an if condition in single square brackets with a simple comparison operator like equals, greater than etc, for example:

上下文:单个方括号中的 if 条件,带有一个简单的比较运算符,如等于、大于等,例如:

VARIABLE=$(/some/command);
if [ $VARIABLE == 0 ]; then
  # some action
fi 

回答by user56reinstatemonica8

If your $VARIABLEis a string containing spaces or other special characters, and single square brackets are used(which is a shortcut for the testcommand), then the string may be split out into multiple words. Each of these is treated as a separate argument.

如果您$VARIABLE的字符串包含空格或其他特殊字符,并且使用单个方括号(这是test命令的快捷方式),则该字符串可能会被拆分为多个单词。这些中的每一个都被视为一个单独的参数。

So that one variable is split out into many arguments:

因此,一个变量被拆分为多个参数

VARIABLE=$(/some/command);  
# returns "hello world"

if [ $VARIABLE == 0 ]; then
  # fails as if you wrote:
  # if [ hello world == 0 ]
fi 

The same will be true for any function call that puts down a string containing spaces or other special characters.

对于任何放下包含空格或其他特殊字符的字符串的函数调用,情况也是如此。



Easy fix

轻松修复

Wrap the variable output in double quotes, forcing it to stay as one string (therefore one argument). For example,

将变量 output 用双引号括起来,强制它保留为一个字符串(因此是一个参数)。例如,

VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
  # some action
fi 

Simple as that.But skip to "Also beware..." below if you also can't guarantee your variable won't be an empty string, or a string that contains nothing but whitespace.

就那么简单。但是,如果您也不能保证您的变量不是空字符串,或者只包含空格的字符串,请跳到下面的“也请注意...”。



Or, an alternate fixis to use double square brackets (which is a shortcut for the new testcommand).

或者,另一种解决方法是使用双方括号(这是new test命令的快捷方式)。

This exists only in bash (and apparently korn and zsh) however, and so may not be compatible with default shells called by /bin/shetc.

但是,这仅存在于 bash(显然是 korn 和 zsh)中,因此可能与/bin/shetc调用的默认 shell 不兼容。

This means on some systems, it might work from the console but not when called elsewhere, like from cron, depending on how everything is configured.

这意味着在某些系统上,它可能从控制台工作,但在其他地方调用时可能无法工作,例如 fromcron,具体取决于所有内容的配置方式。

It would look like this:

它看起来像这样:

VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
  # some action
fi 

If your command contains double square brackets like this and you get errors in logs but it works from the console, try swapping out the [[for an alternative suggested here, or, ensure that whatever runs your script uses a shell that supports [[aka new test.

如果您的命令包含这样的双方括号,并且您在日志中收到错误,但它可以从控制台运行,请尝试更换[[此处建议的替代方法,或者确保运行您的脚本的任何内容都使用支持[[aka的 shell new test



Also beware of the [: unary operator expectederror

还要注意[: unary operator expected错误

If you're seeing the "too many arguments" error, chances are you're getting a string from a function with unpredictable output. If it's also possible to get an empty string(or all whitespace string), this would be treated as zero arguments even with the above "quick fix", and would fail with [: unary operator expected

如果您看到“参数过多”错误,很可能您从具有不可预测输出的函数中获取字符串。如果也有可能得到一个空字符串(或所有空白字符串),即使使用上述“快速修复”,这也将被视为零参数,并且会失败[: unary operator expected

It's the same 'gotcha' if you're used to other languages - you don't expect the contents of a variable to be effectively printed into the code like this before it is evaluated.

如果您习惯于其他语言,它是相同的“问题” - 您不希望变量的内容在评估之前像这样有效地打印到代码中。

Here's an example that prevents both the [: too many argumentsand the [: unary operator expectederrors: replacing the output with a default value if it is empty (in this example, 0), with double quotes wrapped around the whole thing:

这是一个可以防止[: too many arguments[: unary operator expected错误的示例:如果输出为空(在本例中为0),则将输出替换为默认值,并用双引号将整个内容括起来:

VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
  # some action
fi 

(here, the action will happen if $VARIABLE is 0, or empty. Naturally, you should change the 0 (the default value) to a different default value if different behaviour is wanted)

(此处,如果 $VARIABLE 为 0 或为空,则该操作将发生。当然,如果需要不同的行为,您应该将 0(默认值)更改为不同的默认值)



Final note:Since [is a shortcut for test, all the above is also true for the error test: too many arguments(and also test: unary operator expected)

最后说明:由于[是 的快捷方式test,因此上述所有内容也适用于错误test: too many arguments(以及test: unary operator expected

回答by sdaau

Just bumped into this post, by getting the same error, trying to test if two variables are bothempty (or non-empty). That turns out to be a compound comparison - 7.3. Other Comparison Operators - Advanced Bash-Scripting Guide; and I thought I should note the following:

刚碰到这篇文章,遇到同样的错误,试图测试两个变量是否都是空的(或非空的)。结果证明这是一个复合比较 - 7.3。其他比较运算符 - 高级 Bash 脚本指南;我想我应该注意以下几点:

  • I used -ethinking it means "empty" at first; but that means "file exists" - use -zfor testing empty variable(string)
  • String variables need to be quoted
  • For compound logical AND comparison, either:
    • use two tests and &&them: [ ... ] && [ ... ]
    • or use the -aoperator in a single test: [ ... -a ... ]
  • -e起初我以为它的意思是“空”;但这意味着“文件存在” --z用于测试空变量(字符串)
  • 字符串变量需要加引号
  • 对于复合逻辑 AND 比较,可以:
    • 使用两个tests 和&&它们:[ ... ] && [ ... ]
    • -a在单个中使用运算符test[ ... -a ... ]

Here is a working command (searching through all txt files in a directory, and dumping those that grepfinds contain both of two words):

这是一个工作命令(搜索目录中的所有 txt 文件,并转储grep找到的那些包含两个单词的文件):

find /usr/share/doc -name '*.txt' | while read file; do \
  a1=$(grep -H "description" $file); \
  a2=$(grep -H "changes" $file); \
  [ ! -z "$a1" -a ! -z "$a2"  ] && echo -e "$a1 \n $a2" ; \
done


Edit 12 Aug 2013: related problem note:

2013 年 8 月 12 日编辑:相关问题说明:

Note that when checking string equality with classic test(single square bracket [), you MUSThave a space between the "is equal" operator, which in this case is a single "equals" =sign (although two equals' signs ==seem to be accepted as equality operator too). Thus, this fails (silently):

请注意,在使用经典test(单方括号[)检查字符串相等性时,“等于”运算符之间必须有一个空格,在这种情况下,它是单个“等号” =(尽管两个等号==似乎被接受为相等运算符)。因此,这失败了(悄悄地):

$ if [ "1"=="" ] ; then echo A; else echo B; fi 
A
$ if [ "1"="" ] ; then echo A; else echo B; fi 
A
$ if [ "1"="" ] && [ "1"="1" ] ; then echo A; else echo B; fi 
A
$ if [ "1"=="" ] && [ "1"=="1" ] ; then echo A; else echo B; fi 
A

... but add the space - and all looks good:

...但添加空间 - 一切看起来都不错:

$ if [ "1" = "" ] ; then echo A; else echo B; fi 
B
$ if [ "1" == "" ] ; then echo A; else echo B; fi 
B
$ if [ "1" = "" -a "1" = "1" ] ; then echo A; else echo B; fi 
B
$ if [ "1" == "" -a "1" == "1" ] ; then echo A; else echo B; fi 
B

回答by wisbucky

Another scenario that you can get the [: too many argumentsor [: a: binary operator expectederrors is if you try to test for all arguments "$@"

另一个可能会出现[: too many arguments[: a: binary operator expected错误的情况是,如果您尝试测试所有参数"$@"

if [ -z "$@" ]
then
    echo "Argument required."
fi

It works correctly if you call foo.shor foo.sh arg1. But if you pass multiple args like foo.sh arg1 arg2, you will get errors. This is because it's being expanded to [ -z arg1 arg2 ], which is not a valid syntax.

如果您调用foo.sh或 ,它可以正常工作foo.sh arg1。但是如果你传递多个参数,比如foo.sh arg1 arg2,你会得到错误。这是因为它被扩展为[ -z arg1 arg2 ],这不是有效的语法。

The correct way to check for existence of arguments is [ "$#" -eq 0 ]. ($#is the number of arguments).

检查参数是否存在的正确方法是[ "$#" -eq 0 ]. ($#是参数的数量)。

回答by Kemin Zhou

Some times If you touch the keyboard accidentally and removed a space.

有时如果您不小心触摸键盘并删除了一个空格。

if [ "$myvar" = "something"]; then
    do something
fi

Will trigger this error message. Note the space before ']' is required.

会触发这个错误信息。注意 ']' 之前的空格是必需的。

回答by Kidane

I have had same problem with my scripts. But when I did some modifications it worked for me. I did like this :-

我的脚本也有同样的问题。但是当我做了一些修改时,它对我有用。我确实喜欢这样:-

export k=$(date "+%k");
if [ $k -ge 16 ] 
    then exit 0; 
else 
    echo "good job for nothing"; 
fi;

that way I resolved my problem. Hope that will help for you too.

这样我就解决了我的问题。希望这对你也有帮助。