我想检查两个变量中的两个都没有设置。我尝试了多种选择,这是我想到的最干净的解决方案:
if [ ! -z $A -a -z $B ] || [ -z $A -a ! -z $B ]; then
#error
fi
#success
当我同时设置A和B来运行脚本时,它运行良好。但是当我在缺少A的情况下运行它时,会得到:
./test.sh: line 3: [: too many arguments
./test.sh: line 3: [: too many arguments
第3行是条件语句。
当我在缺少B的情况下运行它时,我得到:
./test.sh: line 3: [: argument expected
./test.sh: line 3: [: argument expected
是因为我的条件语法错误还是我想念其他东西?
答案 0 :(得分:3)
引用变量:
if [ ! -z "$A" -a -z "$B" ] || [ -z "$A" -a ! -z "$B" ]; then
如果变量未加引号且未设置,则它们将被替换为空,这意味着该命令实际上变为:
if [ ! -z -a -z ] || [ -z -a ! -z ]; then
导致您看到的错误。
答案 1 :(得分:3)
您应尽量避免使用-a
;它是非标准的,并且被POSIX标准视为过时的。由于||
和&&
的优先级相同,因此您需要使用{ ... }
对各个测试进行正确分组。
(这是除了立即需要引用参数扩展之外的内容。)
if { [ ! -z "$A" ] && [ -z "$B" ]; } || { [ -z "$A" ] && [ ! -z "$B" ]; }; then
但是,更简单的表达式可能是
if [ -z "$A$B" ] || { [ "$A" ] && [ "$B" ]; }; then
[ "$A" ]
是[ -n "$A" ]
的缩写,等效于[ ! -z "$A" ]
。使用bash
的{{1}}命令,您可以编写更自然的
[[ ... ]]
在这种情况下,报价是可选的,并且if [[ -z $A && -n $B || -n $A && -z $B ]];
和||
可以在&&
内部使用,并且具有您期望的优先级。
答案 2 :(得分:1)
您忘了在变量周围使用引号:
if [ ! -z "$A" -a -z "$B" ] || [ -z "$A" -a ! -z "$B" ]; then
echo "error"
fi
Bash将用值替换脚本中的var,因此当未设置A=5
和B
时,您的版本将显示为:
if [ ! -z 5 -a -z ] || [ -z 5 -a ! -z ]; then
您看到语法错误,因为-z
需要一个参数。使用引号时,显示为:
if [ ! -z "5" -a -z "" ] || [ -z "5" -a ! -z "" ]; then
如您所见,B
的参数现在是一个空字符串,有效。
如果将A="string with spaces"
设置为无引号,则您的版本也会失败。