Como posso cancelar o restante de uma lista de comandos no Bash?

10

No Bash, ocasionalmente digito uma lista de comandos e bato Enter, e só depois percebo que há um erro com algum comando perto do final da lista. Sei que, se pressionar Ctrl+ C, encerrará o comando em execução no momento e cancelará o restante da lista. Existe alguma maneira de cancelar o restante da lista sem encerrar o comando em execução no momento?

Por exemplo, digamos que digitei algo como

foo; bar

ou

foo && bar

Onde fooé um comando de longa duração que é muito importante para não interromper e barfaz algo irreversível e indesejado (digamos, shutdown -h nowou rm -rf /). Enquanto fooainda está em execução, existe uma maneira geral de dizer ao shell para deixar footerminar, mas não para executar bardepois? (Sim, eu poderia alterar as permissões barpara que não sejam executáveis, mas isso não é particularmente conveniente se baré algo rmque eu quero usar nesse meio tempo, nem funcionará se eu não for o proprietário barou se barfor um built-in.)

Psychonaut
fonte
Você pode modificar o último barcomando para some_command: ^bar^some_commandantes de ser executado.
GAD3R
3
@ GAD3R: mas isso não modifica a linha atual, inicia uma nova.
Arkadiusz Drabczyk 02/04/19

Respostas:

3

Eu observei que usar CtrlZpara mudar o programa para um processo em segundo plano faz o truque.

foo && bar

Agradecemos a @Arkadiusz Drabczyk por apontá-lo em comentários que foo; barnão dão controle da maneira necessária.

Então:

^Z

[1]+  Stopped                 foo

O comando para apenas a primeira tarefa e

fg %1

Isso traz apenas a tarefa foopara o primeiro plano e conclui a tarefa e sai.

PS: Isso pode ser verificado com dois scripts gravados em um arquivo. O primeiro dorme por alguns segundos para dar tempo para ser recolocado.

Estou perdido por que os CtrlZmanipuladores apenas o comando em execução e deixa o resto. Gostaria de conhecer.

Revanth Chetluru
fonte
1
Eu não posso reproduzi-lo. Qual bashversão você usa? Eu uso GNU bash, version 4.3.46(1)-release (x86_64-slackware-linux-gnu). Eu escrevi 2 scripts bash que gravam em arquivos diferentes write1.sh:: pastebin.com/rbKmdWgB e write2.sh: pastebin.com/bNx3VRws . Eu executá-los assim: ./write1.sh ; ./write2.sh. O primeiro script ecoa wrote 1por algumas vezes, pressiono C-z, diz [1]+ Stopped ./write1.she posso ver imediatamente a saída do segundo script: wrote 2sendo repetidamente repetido.
Arkadiusz Drabczyk
2
Eu acho que a razão pela qual esse método funciona com command1 && command2pipelines é que Control-zenvia SIGCHLDsinal para o processo. Pode ser verificado com echo $?. Bashentão vê que o primeiro processo não foi concluído com êxito e não executa os próximos processos.
Arkadiusz Drabczyk
Eu estou usando GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16). Sim, acho que você está certo. foo; barnão pode ser controlado da maneira desejada. Mas podemos fazer a parada necessária do segundo processo com Ctrl+Zse o comando for executado foo && bar. Vou atualizar a resposta. Obrigado por apontar.
Revanth Chetluru
@ArkadiuszDrabczyk não Ctrl-Z envia SIGTSTP?
Muni
O @RevanthChetluru observa que barainda está suspenso e aparece na jobssaída, portanto provavelmente também deve ser eliminado .
Muru3