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

23

Eu sigo este padrão de suspender a tarefa e depois deixá-la continuar com muita frequência com a sequência Ctrl-Z bg .

Eu queria saber se há alguma maneira de comprimir isso para pressionar uma única tecla?

Meu shell é zsh

    
por Evgeniy Dolzhenko 13.01.2012 / 15:12

4 respostas

23

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

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

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

Alguns sistemas, incluindo o Linux, estendem essa lista, mas eu nunca vi um que incluísse o plano de fundo. Observe que seria necessário suporte no driver de 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 um sinal SIGTSTP . Isso dispara um SIGCHLD no processo pai do líder do trabalho em primeiro plano, que geralmente é o shell. Quando o shell recebe o SIGCHLD, ele chama waitpid para descobrir por que foi notificado e após a detecção de que um trabalho em segundo plano foi suspenso, ele exibe uma notificação (por exemplo, [1] + 12345 suspended mycommand ) e um novo prompt.

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

O que eu faço é definir a seqüência de teclas Ctrl + Z em zsh para o plano de fundo do trabalho atual ( %% ). Dessa forma, posso enviar o trabalho em primeiro plano para o plano de fundo pressionando Ctrl + Z Ctrl + Z . Enquanto faço isso, eu faço Ctrl + Z fazer outra coisa útil quando a linha de entrada atual não está vazia (então eu não acabei de voltar de um subprocesso ): “Suspende” a linha de entrada atual, permitindo que eu digite outro comando, após o qual a linha interrompida é colocada de volta no 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
    
por 13.01.2012 / 16:30
1

Então, encontrei a solução, não exatamente o que eu quero, mas muito perto daqui link

On an empty command line runs bg (so that Ctrl+Z Ctrl+Z suspends a program and immediately resumes it in the background).

    
por 13.01.2012 / 15:39
1

^ z ^ z como 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 ^ @'

so ^ z para suspensão é ativado quando um comando é executado e, em seguida, desativado para o prompt bash.

    
por 27.01.2018 / 04:52
0

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

    
por 18.01.2012 / 03:25