Por que o IGNOREEOF não funciona no Zsh?

1

Eu uso freqüentemente o Ctrl-D para sair das sessões interativas do Python, mas às vezes eu acidentalmente o atingia quando a sessão do Python não estava ativada. Isso resultará em enviar um EOF para o shell e, em seguida, fechá-lo (sem solicitar confirmação). Eu vim a duas soluções de googling ao redor:

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

A primeira opção funcionou perfeitamente no meu shell zsh e bash. No entanto, a segunda opção parece funcionar apenas no bash. Quando estou em zsh, seja qual for o número que eu configurei para IGNOREEOF , ele envia EOF como se não estivesse definido.

Alguém pode me ajudar com o porquê do ZSH se comportar dessa maneira ou é apenas o resultado de alguma configuração peculiar do env no meu shell zsh?

    
por Zhenhua 22.08.2017 / 03:39

1 resposta

2

O Zsh não usa o parâmetro IGNOREEOF como o Bash. Em vez disso, é uma opção que você deve definir por meio do setopt builtin. De zshoptions(1) :

IGNORE_EOF (-7)

Do not exit on end-of-file. Require the use of exit or logout instead. However, ten consecutive EOFs will cause the shell to exit anyway, to avoid the shell hanging if its tty goes away.

Also, if this option is set and the Zsh Line Editor is used, widgets implemented by shell functions can be bound to EOF (normally Control-D) without printing the normal warning message. This works only for normal widgets, not for completion widgets.

- O segundo parágrafo é importante se você deseja emular o IGNOREEOF do Bash; veja abaixo

Você pode ativar essa opção adicionando o seguinte à sua configuração de shell:

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

Emulando Bash (Opcional)

Se você gostaria de emular o comportamento de Bash de poder especificar o número de seqüências Ctrl + D antes de sair do shell, então você pode adicionar o seguinte < uma definição de widget ZLE * para sua configuração:

# 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
}

Em seguida, adicione o widget ao ZLE e crie um atalho para ele:

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

Você ainda precisará definir a opção ignore_eof , caso contrário Ctrl + D irá ignorar o ZLE e sair imediatamente do shell, independentemente deste widget. Consulte o segundo parágrafo do snippet man page no início da resposta.

* - O crédito por este widget vai para seu autor original, Christoph Lange, e Bart Schaefer por suas correções

    
por 02.04.2018 / 04:47