我在一个Bash脚本中遇到了"unary operator expected"的错误。

15

在我的Bash脚本中,我有一个函数来返回0或1(true或false),以供后续的main函数作为条件判断。

function1 () {
    if [[ "${1}" =~ "^ ...some regexp... $" ]] ; then
        return 1
    else
        return 0
    fi
}

然后在我的主函数中:

main () {
    for arg in ${@} ; do
        if [ function1 ${arg} ] ; then
            ...
        elif [ ... ] ; then
            ...
        fi
    done
}

然而,当我运行这个脚本时,总是会出现错误消息:

[: function1: 期望一元运算符

我该如何修复它?


1
请注意,在bash版本4中,您不应引用正则表达式:这样做会强制进行简单的字符串匹配--在此处记录。此外,您应该使用带引号的for arg in "$@",或更简单的for arg; do ... - glenn jackman
1
你应该将正则表达式放在一个变量中。pattern='^ ...some regexp... $'; if [[ $1 =~ $pattern ]]。请注意,在双方括号内,不需要引用变量,正如Glenn所说,正则表达式(变量)永远不应该被引用。 - Dennis Williamson
如果在Bash条件语句中出现“需要一元运算符”错误,可以使用规范的方法。 - Peter Mortensen
1个回答

33

你正在犯一个常见的错误,认为[if命令语法的一部分。实际上不是,if的语法非常简单。

if command; then
    ... things which should happen if command's result code was 0
else
    ... things which should happen otherwise
fi

我们常用的一个命令是[,它是test命令的别名。这是一个用于比较字符串、数字和文件的简单命令。它只接受一些特定的参数组合,如果你没有传递预期的参数,它通常会生成令人困惑和误导的错误消息。(或者说,一旦你习惯了这些错误消息,它们是足够清晰和有用的,但如果你不习惯的话,很容易误解。)

在你的main函数中,调用[似乎放错了位置。你可能是指

if function "$arg"; then
    ...
elif ... ; then ...
顺便提一下,为了保险起见,您还应该始终引用字符串。使用"$1"而不是$1,并使用"$arg"代替$argtest作为作者不想将其作为if语法的一部分的通用杂物堆的历史原因是原始Bourne shell设计中较不具吸引力的设计之一。 Bash和zsh提供了更不笨重的替代方案(例如bash中的双方括号[[,您在function1定义中使用),当然,POSIX test比贝尔实验室的原始版本更加温和。
另外需要澄清的是,您的函数可以简化为:
function1 () {
    ! [[ "$1" =~ "^ ...some regexp... $" ]]
}

也就是,使用[[进行测试,并反转其结果代码。(通常情况下,成功返回0,但也许您正在尝试验证字符串不匹配?)


这些...代表${1}后面的脚本,在我的实际脚本中,我仔细地用一个空格分隔了我的脚本和括号。所以我不认为这是问题所在。 - GJ.
不,我的函数1实际上检查$1是否匹配某种正则表达式。而且我的函数1单独运行时完全正常。所以我认为问题在于我的主函数中的条件判断出了一些问题。 - GJ.
哦,抱歉,我在“main”中错过了错误。谢谢你的提示。基本分析仍然成立;“[`不是你想象中的那样。 - tripleee
谢谢!我不应该在主函数的条件中使用括号。谢谢! - GJ.
我将这个答案重新用于 https://dev59.com/7pXfa4cB1Zd3GeqPiatH#36371520,那是一个更专注的问题。如果你被链接到这里,请点击进入更新的问题。 - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接