Клавиши со стрелками в MacOS/iTerm2/fish перестают работать после завершения процесса с помощью Ctrl+C

Я думаю, что вы видели рекомендацию для 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

хотя бы для кш , баш , зш .

Таким образом, [[ ]]имеет улучшенное поведение как по сравнению с [ ], так и с прямыми логическими операторами оболочки.

0
15.09.2021, 02:13
1 ответ

Программа переключилась в режим приложения для курсора -клавиш (и не выполняет очистку при прерывании ). Вы можете вручную переключиться обратно с помощью этой команды:

tput rmkx

В некоторых эмуляторах терминала есть настройка в диалоговом окне, позволяющая сделать то же самое.

2
15.09.2021, 08:25

Теги

Похожие вопросы