if [](方括号)中的“ [:过多参数”错误的含义

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


错误:


-bash: [: too many arguments

Google友好版本: bash open square bracket colon too many arguments。


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


VARIABLE=$(/some/command);

if [ $VARIABLE == 0 ]; then

  # some action

fi 


慕桂英546537
浏览 1147回答 3
3回答

汪汪一只猫

如果您$VARIABLE的字符串是包含空格或其他特殊字符的字符串,并且使用了一个方括号(这是test命令的快捷方式),则该字符串可能会拆分为多个单词。这些每个都被视为一个单独的参数。因此,一个变量被分成许多参数:VARIABLE=$(/some/command);  # returns "hello world"if [ $VARIABLE == 0 ]; then  # fails as if you wrote:  # if [ hello world == 0 ]fi 对于放下包含空格或其他特殊字符的字符串的任何函数调用,也是如此。容易修复将变量输出用双引号引起来,强制其保留为一个字符串(因此为一个参数)。例如,VARIABLE=$(/some/command);if [ "$VARIABLE" == 0 ]; then  # some actionfi 就那么简单。但是,如果您也不能保证变量不会是一个空字符串,或者除了空格以外就什么都不是的字符串,请跳到下面的“也请注意...”。或者,另一种解决方法是使用双方括号(这是该new test命令的快捷方式)。但是,它仅存在于bash(显然是korn和zsh)中,因此可能与/bin/shetc 调用的默认shell不兼容。这意味着在某些系统上,它可能可以在控制台上运行,但在其他地方(例如从)调用时则不能cron,具体取决于所有配置方式。它看起来像这样:VARIABLE=$(/some/command);if [[ $VARIABLE == 0 ]]; then  # some actionfi 如果您的命令包含这样的双方括号,并且您在日志中遇到错误,但可以从控制台运行,请尝试将换成[[此处建议的替代方法,或者确保运行脚本的任何东西都使用支持[[aka 的外壳new test。还要提防[: unary operator expected错误如果看到“参数太多”错误,则很可能是您从函数中获得了一个字符串,该字符串的输出不可预测。如果还可以获取一个空字符串(或所有空白字符串),那么即使使用上述“快速修复”,也将其视为零参数,并且将失败[: unary operator expected如果您习惯于其他语言,则这是相同的“陷阱”-您不希望变量的内容在评估之前像这样被有效地打印到代码中。这是一个防止[: too many arguments和[: unary operator expected错误的示例:如果输出为空,则将其替换为默认值(在此示例中为0),并用双引号引起来:VARIABLE=$(/some/command);if [ "${VARIABLE:-0}" == 0 ]; then  # some actionfi (此处,如果$ VARIABLE为0或为空,则将执行该操作。自然地,如果需要不同的行为,则应将0(默认值)更改为其他默认值)最后说明:由于[是的快捷方式test,因此上述所有错误均适用test: too many arguments(并且也适用test: unary operator expected)

幕布斯7119047

刚刚碰到这个帖子,通过得到相同的错误,试图测试两个变量是否均为空(或非空)。事实证明这是一个复合比较-7.3。其他比较运算符-高级Bash脚本编写指南;我想我应该注意以下几点:我曾经-e以为一开始它意味着“空”。但这意味着“文件存在”- -z用于测试空变量(字符串)字符串变量需要加引号对于复合逻辑与比较,可以:使用两个tests和&&它们:[ ... ] && [ ... ]或-a单独使用运算符test:[ ... -a ... ]这是一个有效的命令(搜索目录中的所有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编辑2013年8月12日:相关问题注释:请注意,当用classic test(单方括号[)检查字符串是否相等时,“ is equal”运算符之间必须有一个空格,在这种情况下,它是一个“ equals” =符号(尽管两个equals的符号==似乎被视为相等)运营商)。因此,这将失败(无提示):$ 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...但是增加空间-一切看起来都不错:$ 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
打开App,查看更多内容
随时随地看视频慕课网APP