Como posso obter uma confirmação antes de sair da tela?

3

Como posso obter uma confirmação antes de sair da tela (ao digitar exit na linha de comando). Isso é possível?

    
por Taapo 11.04.2018 / 11:11

2 respostas

2

Eu me aproximei disso mascarando o comando exit com uma função; a função verifica se você está na tela e se você é o único processo filho que resta desse processo de tela.

exit() {
  if  [[ "$(ps -o pid= --ppid "$(ps -o ppid= -p "$$")" | wc -l)" -eq 1 ]]
  then
    read -p "Warning: you are in the last screen window; do you really want to exit? (y/n) "
    case $REPLY in
        (y*) command exit "$@" ;;
    esac
  else
    # not within screen at all, or not within the last screen window
    command exit "$@"
  fi
}

Você teria que incluir essa função como parte do seu perfil (bash), por exemplo %código%. Ao iniciar a tela, (a menos que seja dito o contrário), inicie uma instância de seu $ SHELL. Esse shell será filho de um processo de tela. Ao sair de um shell filho, o código acima verifica quantos processos são filhos do processo pai do shell atual. De dentro para fora:

  • ~/.bash_profile - pede o PID pai (adicionando o $(ps -o ppid= -p "$$") suprime a linha de cabeçalho) do processo atual ( = )
  • $$ - pede a lista de PIDs (novamente sem o cabeçalho) cujo pai PID é nosso pai, então conta o número de linhas de saída

Se parece que somos o último processo filho de uma sessão de tela, ele solicita confirmação; se a resposta começar com a letra $(ps -o pid= --ppid ... | wc -l) , a função chamará o comando "real" y para sair do shell; caso contrário, a função termina sem sair do shell.

Se não formos o último processo filho, a função continua e sai normalmente.

Algumas notas foram desenvolvidas:

  • Inicialmente tive mais testes na linha exit para ver se estamos em uma sessão de tela, inclusive ver se if está preenchida e se STY é maior que 1. a tela define STY e O bash irá incrementar o SHLVL, mas nenhuma dessas variáveis é somente leitura, então o teste não é strong o suficiente para ser útil.

  • A tela
  • também define uma variável SHLVL , mas a verificação de WINDOW não é confiável; você pode abrir duas janelas e fechar a janela 0 , deixando a janela 0 como a última janela.

  • Digitar EOF (normalmente Controle + D ) fará com que o shell saia imediatamente, ignorando esta função do invólucro. A melhor solução que eu sei seria definir a variável 1 para algum valor diferente de zero; Isso só vai atrasar a inevitável saída da Shell.

Como eu usei muitos recursos específicos bash- (e GNU procutils-) acima, eu também quis fornecer uma solução em conformidade com POSIX. A linha IGNOREEOF muda para um esquema ps para capturar o número de processos com um PID pai específico. A outra mudança é re-trabalhar o ps ... | grep -c em um prompt separado e read -p .

exit() {
  parent="$(ps -o ppid= -p $$)"
  if [ "$( ps -eo ppid= | grep -c "^ *${parent}\$" )" -eq 1 ]
  then
    printf "Warning: you are in the last screen window; do you really want to exit? (y/n) "
    read REPLY
    case $REPLY in
        (y*) command exit "$@" ;;
    esac
  else
    # not within screen at all, or not within the last screen window
    command exit "$@"
  fi
}
    
por 14.04.2018 / 03:47
0

Eu suponho que você esteja usando o bash.

are_u_sure(){
        read -n1 -p "Are you sure to exit? [y/N] "
        [ "$REPLY" != y ] && { echo; history -a; bash; }
}

trap are_u_sure EXIT

Adicione isto ao seu ~ / .bashrc, e sempre que você tentar sair do bash (digite exit ou ^ D), você será solicitado. E você nunca sairá a menos que você pressione 'y'.

Dessa forma, não precisamos nos ater à magia da tela, já que podemos fazer isso em todo o mundo.

Como esta abordagem é extremamente simples, ela tem uma falha, você perderá as atribuições de variáveis digitadas anteriormente. Mas pode ser que possamos trabalhar nisso. Você pode modificar este código para atender às suas necessidades de qualquer maneira.

    
por 14.04.2018 / 10:18