XOR условно в Баш - PullRequest
       26

XOR условно в Баш

0 голосов
/ 21 июня 2019

Я хочу посмотреть, установлена ​​ли какая-либо из двух переменных, но не обе в bash.

У меня есть что-то подобное, но я не уверен насчет синтаксиса. Я знаю, что оператор xor не логичен и должен использоваться как побитовый, но как я могу разобрать [-z "$ tag"] в 1 или 0 вместо true или false

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

Ответы [ 2 ]

3 голосов
/ 21 июня 2019
! 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 … ].

2 голосов
/ 21 июня 2019

Лучшее, что я могу придумать:

if [ "${tag:+A}" != "${flag:+A}" ]; then
    echo yes
else
    echo no
fi

"${foo:+bar}" расширяется до bar, если foo не пусто, и пустая строка в противном случае.

"${tag:+A}" нормализует значение $tag: если оно пустое, оно остается пустым;если оно не пустое, оно превращается в A.

xor - это просто неравенство по логическим значениям.Здесь мы используем неравенство для нормализованных строк вместо этого, что обеспечивается оператором != [.


Для общего решения с двумя произвольными командами foo и bar (не только тесты is-string-empty), вы можете использовать следующее:

if if foo; then ! bar; else bar; fi; then
    ...
else
    ...
fi

Это выглядит немного ужасно, и вам нужно повторить bar дважды, но я не могу придумать более краткогоспособ выразить это.

Вы можете запустить обе команды заранее и сохранить их состояния выхода в переменных, что уберет повторение bar, но в целом увеличит код.

...