我想看看是否设置了两个变量中的任何一个,但在bash中都没有设置。
我有类似的东西,但是我不确定语法。我知道xor运算符确实不合逻辑,应该按位使用,但是我怎么能将[-z“ $ tag”]解析为1或0而不是true或false
if [ -z "$tag" ] ^ [ -z "$flag" ]; then
echo yes
else
echo no
fi
答案 0 :(得分:3)
! testA; TESTA=$?
! testB; TESTB=$?
if [ $TESTA -ne $TESTB ]; then
echo 'Exactly one of testA or testB was true -- the other was not'
fi
testA
和testB
可以是任意程序/管道,例如[ -z "$tag" ]
或[ -z "$flag" ]
。重要的部分是反转带有!
前缀的返回码,以便将0
转换为1
,将1-255
转换为0
,以减少集合可能的退出代码设置为二进制0
或1
。然后,您可以安全地检查两者是否[ … -ne … ]
不同。
答案 1 :(得分:2)
我能想到的最好的事情:
if [ "${tag:+A}" != "${flag:+A}" ]; then
echo yes
else
echo no
fi
如果"${foo:+bar}"
非空, bar
扩展为foo
,否则为空字符串。
"${tag:+A}"
标准化$tag
的值:如果为空,则保持为空;否则,为空。如果为非空,则变为A
。
xor
只是布尔值的不等式。在这里,我们对归一化的字符串使用非等式,它由!=
的{{1}}运算符提供。
对于具有两个任意命令[
和foo
的常规解决方案(不仅仅是is-string-empty测试),可以使用以下命令:
bar
它看起来有点糟糕,您需要重复if if foo; then ! bar; else bar; fi; then
...
else
...
fi
两次,但是我想不出一种更简洁的表达方式。
您可以预先运行这两个命令,并将它们的退出状态保存在变量中,这将删除bar
重复,但会使代码总体上更长一些。
答案 2 :(得分:0)
感谢 melpomene
的回答,我找到了一种方法可以将这种逻辑推广到任意数量的变量
如果您想检查 $varA xor $varB xor $varC
您可以执行以下操作:
SIMULATE_XOR="${varA:+A}${varB:+A}${varC:+A}"
if [[ "${SIMULATE_XOR}" != "A" ]]; then
echo "you must set one, and only one variable"
fi