Ctrl-Z, por vezes, requer Enter para retornar ao prompt do shell

2

Estou logado no terminal (ou emulador de terminal), leio man pages ou leio um arquivo com less , etc. Eu uso Ctrl - Z para suspender o aplicativo em primeiro plano, retornar ao shell (bash), fazer algo, voltar para o aplicativo de tela inteira, sair novamente, etc.

Eventualmente, mas normalmente não durante a primeira iteração, Ctrl - Z não me levará ao prompt de comando, mas permanece em um estado intermediário onde a entrada do teclado é exibida o terminal, a edição readline não está disponível, a exclusão backspace funciona e a entrada digitada é dada ao shell ao pressionar Enter .

Alguém pode explicar por que isso está acontecendo e como desativá-lo? Eu não encontrei nenhuma referência a este fenômeno na internet, apesar de tê-lo encontrado por anos.

    
por T Nierath 07.05.2018 / 12:50

1 resposta

1

Eu posso explicar, mas não sei como consertar isso. Está me incomodando há anos também. Pelo menos 20. Não é um único bug em qualquer programa em particular, mas uma condição de corrida entre 3 programas que estão se comportando individualmente como planejados, e é geral o suficiente para se aplicar a muitas combinações de programas.

Quando você digita ^Z durante a leitura de uma página man, envia um SIGTSTP para o grupo de processos em primeiro plano, que consiste no man process e seus descendentes. O pager ( less ) é um desses descendentes.

man é suspenso imediatamente, mas less não é. Tem um manipulador de sinal. E há uma boa razão para isso. Ele mudou o modo tty (para poder ler os caracteres assim que eles são digitados), e quer restaurar o modo original e arrumar a tela antes de abrir mão do controle. Então isso acontece.

Enquanto isso (essa é uma palavra animada), o shell notou que o processo man está parado. E aqui está a parte ruim: o shell não tem idéia de que o processo less existe. Os processos Unix geralmente não têm como saber sobre seus netos. Então, do ponto de vista do shell, o trabalho parou, mesmo que na realidade less ainda não tenha terminado de arrumar.

Atuando em informações incompletas, o shell se coloca de volta em primeiro plano, imprime uma mensagem de notificação de trabalho, configura o modo tty para seu próprio editor de linhas e imprime um prompt. Mas está correndo com less , que ainda está tentando arrumar. Enquanto o shell está imprimindo um prompt e definindo o modo atty, menos está ocupado movendo o cursor e limpando a linha inferior da tela (onde estava o prompt less ).

Por ser uma corrida, há muitos resultados possíveis, dependendo da ordem das operações, mas a mais irritante é a seguinte:

  1. o shell imprime a notificação de trabalho, define o modo tty para seu editor de linhas e imprime um prompt.
  2. less move o cursor para o canto inferior esquerdo, limpa a linha inferior (apagando o prompt less e o prompt do shell) e restaura o modo tty padrão genérico (modo "cozido").
  3. o shell se coloca em primeiro plano e começa a aceitar entrada.

Agora você está olhando para uma linha em branco precedida por uma notificação de trabalho, com o shell tentando ler pressionamentos de tecla, não sabendo que o tty foi configurado para o modo cozido e, portanto, não enviará nenhuma entrada para o shell até que uma linha completa seja digitada.

Você pode realmente digitar um comando aqui, e até mesmo editá-lo, se for inteligente o bastante para descobrir como fazer com que sua entrada seja passada pelo editor de linha do tty e pelo editor de linha do shell, com feedback imediato vindo apenas do editor de linha do tty.

É uma situação complicada, e consertar parece exigir mais coordenação entre os processos do que o kernel atualmente permite. O shell precisa de uma maneira de consultar o estado de suspensão do grupo de processos como um todo e uma maneira de distinguir entre processos netos como less que manipulam SIGTSTP com a intenção de suspender-se logo depois, e netos tipo daemon que são apenas ignorando SIGTSTP com a intenção de continuar executando em segundo plano enquanto o restante do trabalho é suspenso.

    
por 08.05.2018 / 01:55