如果您$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 action
fi
就那么简单。但是,如果您也不能保证您的变量不会是一个空字符串,或者除了空格之外就什么都不是的字符串,请跳到下面的“也要当心...”。
或者,另一种解决方法是使用双方括号(这是该new test
命令的快捷方式)。
但是,它仅存在于bash(显然是korn和zsh)中,因此可能与/bin/sh
etc 调用的默认shell不兼容。
这意味着在某些系统上,它可能可以在控制台上运行,但在其他地方(例如从)调用时则不能cron
,这取决于所有配置方式。
它看起来像这样:
VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
# some action
fi
如果您的命令包含这样的双方括号,并且您在日志中遇到错误,但可以从控制台运行,请尝试将换成[[
此处建议的替代方法,或者确保运行脚本的任何东西都使用支持[[
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 action
fi
(此处,如果$ VARIABLE为0或为空,则将执行该操作。自然地,如果需要不同的行为,则应将0(默认值)更改为其他默认值)
最后说明:由于[
是的快捷方式test
,因此上述所有错误均适用test: too many arguments
(并且也适用test: unary operator expected
)