1

我意识到这是一个简单的问题,但由于 bash 中的语法要求很复杂,我发现很难得到答案。我有以下脚本:

if ! [ [ -z "$1" ] || [ -z "$2" ] ]; then
  echo "both arguments are set!"
fi

当我不带参数运行它时,我得到以下输出:

./test: line 3: [: -z: binary operator expected 
both arguments are set!

我不期待任何输出 - 两个参数都没有设置。我究竟做错了什么?

4

3 回答 3

6

方括号不是bash. [只是test命令的别名,参数被正常解析。And||是一个分隔命令的 shell 操作符。

如果要对多个命令进行分组,可以使用()subshel​​l 语法。

if ! ([ -z "$1" ] || [ -z "$2" ]);

{ }分组语法:

if ! { [ -z "$1" ] || [ -z "$2" ]; };

或者,您可以使用对 的单个调用test,并使用其内置-o运算符:

if ! [ -z "$1" -o -z "$2" ]
于 2015-10-08T08:31:49.737 回答
5

内置的testshell[支持参数-a-o它们分别是逻辑 AND 和 OR。

#!/bin/sh 

if [ -n "$1" -a -n "$2" ]
then echo "both arguments are set!"
fi

在这里,我-n用来检查字符串的长度是否非零,而不是-z显示它们长度为零,因此必须用 a 取反!

" -n string 如果字符串的长度不为零,则为真。"

"-z string 如果字符串的长度为零,则为真。"

如果您正在使用bash它,它还支持更强大的测试类型[[]],可以使用布尔运算符||&&

#!/bin/bash 

if [[ -n "$1" && -n "$2" ]]
then echo "both arguments are set!"
fi

在评论中,这些示例都没有显示如何在 shell 中否定多个测试,这是一个示例:

#!/bin/sh 

if [ ! -z "$1" -a ! -z "$2" ]
then echo "both arguments are set!"
fi
于 2015-10-08T08:42:19.867 回答
4

请记住(或学习!)这[不是shell 语法一部分,它是一个命令。

如果要将多个命令组合在一起,则应使用{ }

if ! { [ -z "$1" ] || [ -z "$2" ]; }

请注意,解析器希望在结束之前看到行尾或分号}

作为记录,我会避免否定并&&在这里使用:

if [ -n "$1" ] && [ -n "$2" ]

...并且由于您指定了,您还可以利用增强的测试构造:

if [[ -n $1 && -n $2 ]]
于 2015-10-08T09:11:07.553 回答