Como posso pressionar Ctrl-Z e bg em um pressionamento de tecla para fazer o processo continuar em segundo plano?

25

Sigo esse padrão de suspensão da tarefa e, em seguida, deixo que ela continue com muita frequência na Ctrl-Z bgsequência.

Eu queria saber se existe alguma maneira de comprimir isso para pressionar uma tecla?

Minha concha é zsh

Evgeniy Dolzhenko
fonte
Eu quero dizer que provavelmente é codificado. Mas eu não sou 100%
Chad Harrison
Claro que é, mas eu encontrei a solução elegante, obrigado superuser.com/a/161922/35223
Evgeniy Dolzhenko

Respostas:

24

A sequência Ctrl+ Zé manipulada pelo terminal, não pelo shell. (Contexto útil: Qual é a diferença exata entre um 'terminal', um 'shell', um 'tty' e um 'console'? )

Somente um conjunto pequeno e não extensível de funções pode ser vinculado a uma chave em um terminal . Você pode personalizar as teclas associadas a essas funções, mas não adicionar outra função. Essas funções se enquadram em três categorias:

  • Edição de linha de comando em programas que não fornecem seus próprios (modo canônico, também chamado de modo cozido (por oposição ao modo bruto), que você raramente usará na prática): final do arquivo ( eof, Ctrl+ D), final da linha ( eol,Ctrl + M), apaga o caractere à esquerda ( erase, Ctrl+ H), apaga a palavra à esquerda ( werase, Ctrl+ W), apaga a linha ( kill, Ctrl+ U).
  • Controle de fluxo manual: stop( Ctrl+ S), start( Ctrl+ Q). Útil apenas em terminais seriais antigos que eliminavam caracteres quando o terminal não conseguia acompanhar o computador ou vice-versa.
  • Sinalização: interrupção (intr , Ctrl+ C), força encerrada ( quit, Ctrl+ \), suspensão ( Ctrl+ Z).

Alguns sistemas, incluindo Linux, estendem essa lista, mas nunca vi um que incluísse plano de fundo. Observe que seria necessário suporte no driver do terminal no kernel e no emulador de terminal. Então você tem que se contentar com a suspensão, que envia o trabalho em primeiro plano a sinal SIGTSTP . Isso aciona um SIGCHLD no processo pai do líder do trabalho em primeiro plano, que geralmente é o shell. Quando o shell recebeu o SIGCHLD, ele chama waitpidpara descobrir por que foi notificado e, ao detectar que um trabalho em segundo plano foi suspenso, ele exibe uma notificação (por exemplo [1] + 12345 suspended mycommand) e um novo prompt.

Você pode programar o shell para enviar um SIGCONTsinal para o trabalho em primeiro plano. Eu não acho que o zsh tenha um gancho para isso, você precisará corrigir o código fonte. E não há como o zsh saber se você realmente queria interromper o programa (oops, esse programa pode estar fazendo a coisa errada, deixe-me suspendê-lo enquanto eu resolvo isso) ou em segundo plano.


O que faço é definir a sequência de teclas Ctrl+ Zno zsh para colocar em segundo plano o trabalho atual ( %%). Dessa forma, posso enviar o trabalho em primeiro plano para o segundo plano pressionando Ctrl+ Z Ctrl+ Z. Enquanto estou nisso, faço Ctrl+ Zfazer algo mais útil quando a linha de entrada atual não está vazia (para que eu não tenha acabado de voltar de um subprocesso): "suspender" a linha de entrada atual, permitindo que eu digite outro comando , após o qual a linha interrompida é empurrada de volta para o buffer de entrada.

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z
Gilles 'SO- parar de ser mau'
fonte
Gilles, esta é uma resposta incrivelmente completa, educativa e atenciosa que eu não esperava receber! Muito obrigado!
Evgeniy Dolzhenko
2

^ z ^ z como o zsh acima é possível no bash, embora seja um pouco desajeitado e eu não executei isso por muito tempo:

  • No seu .inputrc, inclua o mapeamento "\C-z": "bg\n"
  • Na variável bash do PS0, inclua `$ (stty susp ^ z) '
  • Na variável bash PROMPT_COMMAND, inclua 'stty susp ^ @'

então ^ z for suspend é ativado quando um comando é executado e, em seguida, desativado para o prompt do bash.

JohnLittle
fonte
1

Então encontrei a solução, não exatamente o que eu quero, mas muito perto daqui /superuser//a/161922/35223

Em uma linha de comando vazia, executa bg (para que Ctrl + Z Ctrl + Z suspenda um programa e o retome imediatamente em segundo plano).

Evgeniy Dolzhenko
fonte
Vou notar que isso requer zsh; não é suportado no bash. (fora da caixa, de qualquer maneira) #
9137 Kevin M
@ KevinM Você pode escrever uma função análoga no bash (pelo menos a versão básica para fazer Ctrl+Zchamadas bg, não tenho certeza sobre a detecção de uma linha de entrada não vazia).
Gilles 'SO- stop be evil'
0

Esses comandos que você queria executar em primeiro plano inicialmente e depois mudaram para o segundo plano? Não sei se existe uma maneira mais simples de fazer isso. Mas se você deseja executar comandos que estarão em segundo plano, basta adicionar um e comercial ao final da linha. por exemplo, ping google.com &começará a executar ping em segundo plano; você não poderá interagir com ele a menos que digite fg.

octern
fonte
1
Obrigado, o problema é que, às vezes, você não tem idéia de quanto tempo a execução do comando levaria, então você executa de forma interativa e percebe que é melhor deixá-lo continuar em segundo plano. A resposta aceita faz maravilhas para mim, usando-a diariamente!
Evgeniy Dolzhenko
Obrigado pela resposta. A resposta aceita é bem legal!
octern