Qual é o objetivo da suspensão atrasada (Ctrl-Y) no Bash?

30

A parte completa da página do manual do Bash aplicável apenas diz:

Se o sistema operacional no qual o bash estiver em execução suportar o controle de tarefas, o bash conterá recursos para usá-lo. Digitar o caractere de suspensão (normalmente ^ Z, Control-Z) enquanto um processo está em execução faz com que esse processo seja parado e retorna o controle ao bash. Digitar o caractere de suspensão atrasada (normalmente ^ Y, Control-Y) faz com que o processo seja interrompido quando ele tenta ler a entrada do terminal e o controle retornado ao bash. O usuário pode então manipular o estado desse trabalho, usando o bg comando para continuar em segundo plano, ofgcomando para continuar em primeiro plano ou o comando kill para matá-lo. A ^ Z entra em vigor imediatamente e tem o efeito colateral adicional de fazer com que a saída pendente e o cabeçote de impressão sejam descartados.

Eu nunca usei Ctrl- Y; Eu apenas aprendi sobre isso. Eu tenho feito muito bem com Ctrl- Z(suspender) somente.

Estou tentando imaginar o que esta opção é para . Quando isso seria útil?

(Observe que esse recurso não existe em todas as variantes do Unix. Está presente no Solaris e no FreeBSD, mas não no Linux. A configuração correspondente é stty dsusp.)

Talvez menos subjetivamente: existe algo que possa ser realizado com Ctrl- Yque não pode ser realizado com a mesma facilidade Ctrl- Z?

Curinga
fonte
@ Gilles, embora o FreeBSD pareça ter um stty dsusp, não consegui enviar um SIGTSTP em ^ Y (fiz no Solaris). Você já?
Stéphane Chazelas

Respostas:

23

A partir do manual do 4BSD para csh :

A ^Zentra em vigor imediatamente e é como uma interrupção em que a saída pendente e a entrada não lida são descartadas quando digitadas. Há outra tecla especial ^Yque não gera um sinal de PARADA até que um programa tente lê-lo (2). Isso pode ser útil quando você tiver preparado alguns comandos para um trabalho que deseja interromper após a leitura.

Portanto, o objetivo é digitar várias entradas enquanto a primeira está sendo processada e interromper o trabalho após a conclusão.

Random832
fonte
Esta descrição é sutilmente diferente do manual do bash. "... não gera um sinal de STOP até um programa tenta ler isso. " Parece que tudo na entrada de fluxo até o ^Yserá lido com sucesso, em seguida, quando o ^Yfor atingido o processo será interrompido. Estou lendo isso certo?
Curinga
@Wildcard no meu teste no Mac OS X, o processo é interrompido antes read () retorna (mas após a chamada para read () que teria retornado Y runs), e depois de ser retomado recebe a entrada de antes ^ Y . Eu acho que, como isso pretendia ser usado, seria usado no início de uma linha, portanto o comportamento nesse caso não importaria. Suspeito que no código real ele seja suspenso quando o ^ Y teria sido copiado no buffer de leitura do processo do usuário.
usar o seguinte código
Eu estava certo, na função ttread kernel BSD você pode ver isso, e moderna OSX
Random832
Porém, quando o processo for retomado, a chamada será bem-sucedida e conterá os dados digitados no seu terminal antes ^Y, mesmo que você tenha renegado o processo e fechado o terminal antes que o processo seja retomado. Direita? ( "... depois que é retomado, recebe a entrada de antes de ^ Y." Foi o que eu quis dizer; geralmente não ligo no código C.) :) #
Wildcard
Sim. E retorna sem uma nova linha no final, o que é incomum para uma leitura no modo canônico [semelhante a se você digitasse algum texto e depois pressionasse ^ D uma vez] Eu suspeito que eles não pensaram muito nesse caso, pois realmente pretende ser digitado no início de uma linha.
usar o seguinte código
11

Digamos que haja um loop lendo a entrada e executando. Pode ser útil deixar que a tarefa conclua a instrução atual que calcula, sem interrompê-la antes de retornar à linha de comando para uma nova. Então, assim, para terminar um ciclo. Isso encerra o loop normalmente e impede a execução novamente se readestiver sob uma restrição de tempo limite.

Tomasz
fonte
Mas se ele tentar ler as entradas do terminal de qualquer maneira, ele irá parar nesse ponto (e aguardar sua entrada), e você poderá ^Zfazê - lo .
Wildcard
Sim. Veja atualização.
Tomasz
Confira mais um. @Wildcard
Tomasz
11
Mas se tiver um tempo limite, isso também não terminaria normalmente se você não fizesse nada de especial?
Daniel Wagner
11
Poderia. Mas também pode continuar e fazer algum trabalho padrão.
Tomasz
4

Posso pensar em um cenário em que possa ser útil, mas é uma espécie de argumento artificial.

Suponha que você esteja depurando um script que está gravando arquivos temporários que deseja analisar antes de serem excluídos como parte de uma rotina de limpeza.

Você pode adicionar um em read fooalgum lugar depois que os arquivos forem gravados (mas antes da limpeza), executar o script e pressionar Ctrl- Yenquanto eles estão sendo gerados. Você será direcionado para um prompt com o script suspenso em segundo plano para fazer o que for necessário e fgpermitir que o script seja concluído.

DopeGhoti
fonte
11
Parece improvável, porque o script aguardará a entrada de qualquer maneira. Assim, você pode assistir com facilidade a solicitações de entrada e suspendê-lo com ^Z. Em outras palavras: depois de digitar fgvocê terá que dar o script alguma entrada de qualquer maneira antes que ele vai continuar. Daí minha pergunta; Eu ainda não vejo o objetivo ^Y. (Obrigado por responder, no entanto!) :) #
Wildcard
2

O único cenário em que consigo pensar (e nem acho muito convincente) é se você deseja usar algum tipo de digitação antecipada para um comando do shell. Digamos que algum comando esteja em execução, que lerá a entrada em algum momento no futuro. Em seguida, você pode digitá-lo e digitar imediatamente o próximo comando do shell que deseja executar quando o comando em execução for suspenso. Acho que nunca usei isso em várias décadas usando o BSD Unix.

Olaf Seibert
fonte