Я думаю, что вы видели рекомендацию для POSIX sh и/или команды test
, которая удваивается как команда [
, а не конструкцию [[
, которая появилась в ksh (. спасибо Stéphane Chazelas за подсказку )и также используется, например, в bash, zsh и некоторых других оболочках.
В большинстве языков, таких как C, когда уже известно, что предложение истинно или ложно, нет необходимости оценивать оставшиеся части в зависимости от операции :, если истинно, не после логического или после него, если false не после логических и и т. д. Это, конечно, позволяет, например, остановиться, когда указатель равен NULL, и не пытаться разыменовать его в следующем предложении.
Но sh конструкция [ expr1 -o expr2 ]
(включая реализацию bash )не делает этого :она всегда оценивает обе стороны, когда нужно только expr1 для оценки. Возможно, это было сделано для совместимости с реализацией команды test
. С другой стороны, sh's ||
и &&
следуют обычному принципу :не оцениваются, если это не изменит результат.
Таким образом, разница, которую следует отметить, будет:
: > /tmp/effect #clear effect
if [ 1 -eq 1 -o $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
, что дает:
true
or-was-evaluated
Выше каждый [
мог быть заменен на /usr/bin/[
, который является псевдонимом команды test
, использовавшейся до того, как [
был встроен -в оболочки.
В то время как две следующие конструкции:
: > /tmp/effect #clear effect
if [ 1 -eq 1 ] || [ $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
или
: > /tmp/effect #clear effect
if [[ 1 -eq 1 || $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]]; then
echo true;
fi
cat /tmp/effect
Выдаст только true
и оставит effect
пустым:||
ведет себя правильно, и [[
также исправил эту проблему.
ОБНОВЛЕНИЕ:
Как прокомментировал @StéphaneChazelas, я пропустил несколько различий, связанных с первоначальным вопросом. Я просто поставлю здесь самый важный (по крайней мере для меня ):приоритет операторов.
Хотя оболочка не будет учитывать приоритет:
if true || true && false; then
echo true
else
echo false
fi
дает (, потому что нет приоритета, и поэтому сначала оценивается true || true
, а затем&& false
):
false
внутри [[ ]]
оператор &&
имеет приоритет над||
:
if [[ 1 -eq 1 || 1 -eq 1 && 1 -eq 0 ]]; then
echo true
else
echo false
fi
дает (, потому что 1 -eq 1 && 1 -eq 0
сгруппировано и, таким образом, является вторым членом||
):
true
хотя бы для кш , баш , зш .
Таким образом, [[ ]]
имеет улучшенное поведение как по сравнению с [ ]
, так и с прямыми логическими операторами оболочки.
Программа переключилась в режим приложения для курсора -клавиш (и не выполняет очистку при прерывании ). Вы можете вручную переключиться обратно с помощью этой команды:
tput rmkx
В некоторых эмуляторах терминала есть настройка в диалоговом окне, позволяющая сделать то же самое.