bash中的xor条件

时间:2019-06-21 09:12:34

标签: bash xor

我想看看是否设置了两个变量中的任何一个,但在bash中都没有设置。

我有类似的东西,但是我不确定语法。我知道xor运算符确实不合逻辑,应该按位使用,但是我怎么能将[-z“ $ tag”]解析为1或0而不是true或false

if [ -z "$tag" ] ^ [ -z "$flag" ]; then
  echo yes
else 
  echo no
fi

3 个答案:

答案 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

testAtestB可以是任意程序/管道,例如[ -z "$tag" ][ -z "$flag" ]。重要的部分是反转带有!前缀的返回码,以便将0转换为1,将1-255转换为0,以减少集合可能的退出代码设置为二进制01。然后,您可以安全地检查两者是否[ … -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