Como suspender e colocar um processo em segundo plano em primeiro plano

167

Eu tenho um processo originalmente em execução em primeiro plano. Eu suspendi por Ctrl+ Ze, em seguida, retome sua execução em segundo plano por bg <jobid>.

Gostaria de saber como suspender um processo em execução em segundo plano?

Como posso colocar um processo em segundo plano em primeiro plano?

Editar:

O processo é enviado para stderr, então como devo emitir o comando fg <jobid>enquanto o processo está sendo enviado para o terminal?

Tim
fonte
11
Você ainda pode digitar comandos em um terminal que está exibindo erros. O texto espalhado no STDERR não conta como entrada, apenas as teclas que você envia. Parece confuso na tela, mas funciona.
Caleb
@ Caleb: Mesmo quando o processo sai para stdout, ainda posso digitar fg <jobid>para torná-lo em primeiro plano?
Tim
@ Tim: Sim, você pode.
Caleb

Respostas:

216

Como Tim disse, digite fgpara trazer o último processo de volta ao primeiro plano.

Se você tiver mais de um processo em execução em segundo plano, faça o seguinte:

$ jobs
[1]   Stopped                 vim
[2]-  Stopped                 bash
[3]+  Stopped                 vim 23

fg %3para trazer o vim 23processo de volta ao primeiro plano.

Para suspender o processo em execução em segundo plano, use:

kill -STOP %job_id

O sinal SIGSTOP interrompe (pausa) um processo essencialmente da mesma maneira que Ctrl+ Z.

exemplo: kill -STOP %3.

fontes: como enviar sinais para processos no Linux e Unix e como gerenciar trabalhos em segundo plano e em primeiro plano .

fromnaboo
fonte
23
o sinal 19 é SIGCONTpara mim; Eu uso kill -STOPe kill -CONTde preferência a lembrar os números de qualquer maneira, mas você pode verificar kill -lpara lembrar-se dos valores numéricos
Useless
O processo é enviado para stderr, então como devo emitir o comando jobe fg <jobid>enquanto o processo está sendo enviado para o terminal?
Tim
11
@ Tim Basta digitar o comando como faria normalmente. Enquanto o trabalho estiver em segundo plano, ele não estará lendo o que você digita - seu shell é. O que você digita pode parecer ruim para você, mas o shell entenderá perfeitamente.
AlexWebr 8/08
@AlexWebr: Obrigado, funciona! (1) Um trabalho em segundo plano não aceita nenhuma entrada e saída, incluindo "Ctrl + Z" etc, certo? (2) Um trabalho em execução em segundo plano pode ser suspenso diretamente? Se sim, como? Se não, ele deve ser alterado primeiro para ser executado em primeiro plano antes de poder ser suspenso?
Tim
2
Pode um trabalho em execução em segundo plano ser suspenso directamente sim: kill -STOP %job_id, como explicado
Useless
31

Isso deve ser verdade para qualquer shell com controle de trabalho, que (na maior parte) você pode dar por garantido, a menos que lide com um shell verdadeiramente antigo. Está no padrão POSIX , então dashsuporta até o controle de tarefas (quando executado de forma interativa ou com -m).

Interativo

  • Ctrl+ zsuspenderá o programa atualmente em primeiro plano
  • bgfará o plano de fundo do programa suspenso mais recente
    (use bg %2com o número do trabalho, que você pode verificar jobs)
  • fg colocará em primeiro plano o programa suspenso mais recentemente

Em zsh, você pode escrever uma ligação de chave para executar implicitamente a fgpartir do prompt através de outro Ctrl+ z:

_zsh_cli_fg() { fg; }
zle -N _zsh_cli_fg
bindkey '^Z' _zsh_cli_fg

Provavelmente, há também uma maneira inteligente de implicitamente executar bga suspensão, mas parece imprudente; pelo menos para mim, a maioria do meu Ctrl+ zuso é porque o Ctrl+ cestá falhando; Quero seguir isso com, por exemplo, kill %1e não bg, e certamente não quero deixar de matar! (Essa lógica também se estende ao motivo pelo qual eu não uso mais essa ligação de teclas: se eu estiver pressionando o Ctrl+ zpara interromper um processo, a última coisa que eu quero fazer é continuar!)

Não interativo

Se você estiver em uma instância de shell diferente (ou um usuário diferente, às vezes incluindo sudocomandos), provavelmente não poderá usar os números de trabalho.

Você ainda pode atuar em outro processo depois de conhecer seu ID do processo (PID). Você pode obter o PID com pgrep …, ou ps aux |grep …(ou do mesmo shell jobs -l, ou $!) e, em seguida, executar:

kill -STOP $PID  # suspend
kill -CONT $PID  # continue (resume)

Se você não souber o ID do processo e não estiver preocupado em suspender outras instâncias do processo pelo nome, poderá passar sinais para um destes:

killall -STOP program_name
pkill -STOP program_name
pkill -f -STOP program_name_or_args

Um CONTsinal para um programa parado com Ctrl+ z(e não bg'd) continuará seu progresso (em primeiro plano), o mesmo que se você estivesse fgnele.

Re: Erro padrão

A edição desta pergunta pergunta sobre o erro padrão:

O processo é enviado para stderr, então como devo emitir o comando fg <jobid>enquanto o processo está sendo enviado para o terminal?

A menos que o trabalho em questão tenha componentes em segundo plano (ou todo o trabalho seja em segundo plano, talvez via kill -CONT), você não deverá ver a saída enquanto estiver suspensa.

Se ainda estiver emitindo dados (seja na saída padrão ou erro padrão), certamente o seu terminal ficará confuso visualmente, mas toda essa saída será ignorada, pois não faz parte da sua entrada. Isso pode tornar mais difícil saber que você não digitou nenhum erro de digitação, mas (cegamente) a digitação fgEnterdeve ser suficiente (a menos que você tenha vários trabalhos e o item em questão não seja o mais recente, nesse caso, você realmente precisará do descritor de trabalho )

Se você precisar encontrar o descritor de tarefas, use outro terminal para enviar o STOPsinal através dos métodos não interativos acima. Isso deve liberar sua exibição (talvez pressione Enteralgumas vezes ou execute clearou Ctrl+ L) para que você possa executar jobspara encontrar o descritor de tarefa e depois executar fg %Nonde Nestá esse número.

Adam Katz
fonte
O único problema com a pausa e a retomada de processos é que, se você fizesse conexões com algum outro programa (como o RabbitMQ por exemplo), a conexão seria perdida quando você reiniciasse.
Nav
@ Nav - Isso é porque você não o executou sem cabeça. No bash e no zsh, acredito que você apenas precisa renegar um processo em segundo plano. Prefiro executar essas tarefas com nohup ou um multiplexador de terminal como screen ou tmux . Você não pode pegar um processo de nohup (assim como não pode retomar um processo em segundo plano a partir de uma conexão separada), mas pode se conectar a um multiplexador.
Adam Katz
Foi um processo em segundo plano. Fechei o terminal e, em seguida, efetuei login no servidor a partir de outro terminal.
Nav
Sim, você não pode retomar um processo de outro shell, a menos que tenha sido iniciado com isso em mente. Eu recomendo o screen ou tmux para isso.
Adam Katz
Acredito que se você enviar um CONTsinal para um processo (job / pipeline) interrompido com Ctrl + Z, ele será retomado em segundo plano, mesmo se você não bgo tiver.
G-Man
10

Digite fgpara trazê-lo para o primeiro plano.

Tim
fonte
Obrigado! O processo é enviado para stderr, então como devo emitir o comando fg <jobid>enquanto o processo está sendo enviado para o terminal?
Tim
1
  1. listar tarefas com o jobscomando
  2. Traga seu trabalho de destino para o primeiro plano com fg; por exemplo: fg %4
  3. Clique CTRL Zpara suspender
  4. Para iniciá-lo em execução em segundo plano, use bg; por exemplo:bg %4
kmiklas
fonte
0

O término de um processo pode ser feito de várias maneiras diferentes. Freqüentemente, a partir de um comando baseado no console, o envio de uma Ctrlctecla (o caractere de interrupção padrão) sai do comando. Isso funciona quando o processo está sendo executado no modo de primeiro plano.

Se um processo estiver em execução no modo de segundo plano, primeiro você precisará obter seu ID da tarefa usando o pscomando e, em seguida, usar o comando kill para interromper o processo da seguinte maneira:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

Aqui o killcomando encerraria o first_oneprocesso. Se um processo ignorar um killcomando regular , você poderá usar kill -9seguido pelo ID do processo da seguinte maneira:

$kill -9 6738
Terminated
Lakshmi
fonte
11
Embora isto seja verdade, não está respondendo à pergunta ...
jasonwryan