bash - if [] 中 "[: too many arguments"错误的含义(方括号)

标签 bash if-statement arguments

我找不到任何一个简单直接的资源来阐明以下 BASH shell 错误的含义并修复它,所以我发布了我研究后发现的内容。

错误:

-bash: [: too many arguments

Google 友好版本: bash 开方括号冒号参数过多

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

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

最佳答案

如果您的$VARIABLE 是包含空格或其他特殊字符的字符串,and single square brackets are used (这是 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 action
fi 

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


或者,替代修复 是使用双方括号(这是 new test 命令的快捷方式)。

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

这意味着在某些系统上,它可能会在控制台运行,但在别处调用时无法运行,例如 cron,具体取决于一切的配置方式。

看起来像这样:

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

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


还要注意 [: unary operator expected 错误

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

如果您习惯了其他语言,这也是同样的“问题”——您不希望变量的内容在计算之前像这样有效地打印到代码中。

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

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

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


最后说明:因为 [test 的快捷方式,所以以上所有内容对于错误 test: too许多参数(以及测试:预期的一元运算符)

关于bash - if [] 中 "[: too many arguments"错误的含义(方括号),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13781216/

相关文章:

json - 删除存在于同级对象中并具有特定值的键

delphi - 如何使用 "case"语句而不是 "if"语句测试某个值是否在范围内?

c++编译器忽略第一个if语句

Perl:将巨大字符串列表传输到子例程而不复制它们

function - lua不修改函数参数

python - 如何在 Pythonbrew 中使用带空格的位置参数?

regex - sed 从字符串中提取版本号(只有版本,没有其他数字)

linux - 通过 bash 命令注释以查看 pkill

bash - 使用 sed 在捕获组内替换

Java:if语句可以简化(box contains point)