1

Я часто использую Ctrl-D для выхода из интерактивных сеансов Python, но иногда я случайно нажимаю на него, когда сеанс Python не был включен. Это приведет к отправке EOF в оболочку и последующему ее закрытию (без запроса подтверждения). Я пришел к двум решениям от поиска в Google:

  1. set -o ignoreeof
  2. export IGNOREEOF=10

Первый вариант отлично работал в моей оболочке zsh и bash. Однако второй вариант, похоже, работает только в bash. Когда я нахожусь в zsh, какой бы номер я ни установил для IGNOREEOF , он отправляет EOF, как будто он не был установлен.

Может кто-нибудь помочь с тем, почему ZSH ведет себя так или это просто результат какой-то особой настройки env в моей оболочке zsh?

1 ответ1

0

Zsh не использует параметр IGNOREEOF как Bash. Вместо этого это опция, которую вы должны установить через встроенный setopt . Из zshoptions(1):

IGNORE_EOF (-7)

Не выходите в конец файла. Требуйте использования выхода или выхода из системы. Тем не менее, десять последовательных EOF заставят оболочку все равно выйти, чтобы избежать зависания оболочки, если ее tty исчезнет.

Кроме того, если эта опция установлена и используется Zsh Line Editor, виджеты, реализованные функциями оболочки, могут быть связаны с EOF (обычно Control-D) без вывода обычного предупреждающего сообщения. Это работает только для обычных виджетов, а не для виджетов завершения.

- Второй абзац важен, если вы хотите подражать IGNOREEOF Баша; увидеть ниже

Вы можете включить эту опцию, добавив следующее в конфигурацию вашей оболочки:

setopt ignore_eof    # Option names are case-insensitive and underscores are optional.

Эмуляция Bash (необязательно)

Если вы хотите эмулировать поведение Bash, заключающееся в возможности указать количество последовательностей Ctrl+D перед выходом из оболочки, вы можете добавить следующее определение * виджета ZLE * в свою конфигурацию:

# Emulate Bash $IGNOREEOF behavior
bash-ctrl-d() {
  if [[ $CURSOR == 0 && -z $BUFFER ]]
  then
    [[ -z $IGNOREEOF || $IGNOREEOF == 0 ]] && exit
    if [[ $LASTWIDGET == bash-ctrl-d ]]
    then
      (( --__BASH_IGNORE_EOF <= 0 )) && exit
    else
      (( __BASH_IGNORE_EOF = IGNOREEOF-1 ))
    fi
    zle send-break
  else
    zle delete-char-or-list
  fi
}

Затем добавьте виджет в ZLE и создайте для него привязку клавиш:

zle -N bash-ctrl-d
bindkey '^D' bash-ctrl-d

Однако вам все равно нужно будет установить опцию ignore_eof , иначе Ctrl+D проигнорирует ZLE и немедленно выйдет из оболочки независимо от этого виджета. Обратитесь ко второму абзацу фрагмента справочной страницы в начале ответа.

* - Благодарность за этот виджет достается его первоначальному автору Кристофу Ланге и Барту Шеферу за его исправления

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .