Processos em segundo plano sem "&"

24

Digamos que você iniciou um novo aplicativo no Linux (como um editor de texto etc.), mas esqueceu de usar o "&". Quais comandos você usaria para executar esse processo em segundo plano, embora NÃO tivesse que FECHAR esse aplicativo? Dessa maneira, é possível ter os processos abertos e funcionando separadamente (por exemplo, o terminal da linha de comando usado para criar o processo e o processo, como um editor de texto ainda em execução.

D0uble7
fonte
Tecnicamente, não, mas talvez tmuxofereça a mesma funcionalidade desejada na sua pergunta.
Mkc
11
Não negligencie a alternativa simples de abrir outro shell, quando possível.
precisa saber é

Respostas:

43

Na janela do terminal, você normalmente digitava Control+ Zpara "suspender" o processo e, em seguida, usava o bgcomando para "colocá-lo em segundo plano".

por exemplo, com um comando de suspensão

$ /bin/sleep 1000
^Z[1] + Stopped                  /bin/sleep 1000
$ bg
[1]     /bin/sleep 1000&
$ jobs
[1] +  Running                 /bin/sleep 1000
$ 

Podemos ver que o processo está em execução e ainda tenho minha linha de comando.

Stephen Harris
fonte
5
Pode ser interessante acrescentar que o processo pode ser trazido de volta ao primeiro plano com o fgcomando, que leva o ID da tarefa (especificado entre parênteses, 1neste caso) como parâmetro. Não é específico ao uso bge pode ser feito em processos iniciados com &.
Aaron
14

Ctrl+ Zé a maneira de fazê-lo, mas apenas para ser completo: a pergunta pede "comando", e seria (de outro terminal):

kill -STOP pid_of_the_running_applications

e depois é claro

bg

do terminal do aplicativo.

Radovan Garabík
fonte
6
kil -STOP e, em seguida, mate -CONT
Michel Billaud
10

No Bash:

Ctrl+ Ze depois bg.

Agora corra jobse veja o resultado.

Tomasz
fonte
2
@grooveplex Tomas respondeu primeiro, então seria mais apropriado comentar abaixo a resposta de Stephen, que é basicamente a resposta de tomas com mais detalhes.
Anthon
2
Na verdade, respondemos simultaneamente. Não é surpresa que ambos disséssemos a mesma coisa, já que é a resposta óbvia :-) Nenhum de nós copiou o outro. Minha resposta chegou logo após a de Thomas, porque eu havia passado um tempo extra criando e formatando o exemplo.
Stephen Harris
11
E o meu diz que está no Bash, então eles não são os mesmos.
Tomasz
11
Heh, há um ponto potencial lá. Exige que o shell tenha controle de trabalho. Algumas das primeiras máquinas em que trabalhei (baseado SVR2) não tinha isso em /bin/she por isso este não teria funcionado :-)
Stephen Harris
1

Como medida preventiva para a inconveniência de ter que pressionar CTRL- z, você pode criar um script de wrapper para o seu editor, para o qual executaria seu editor em segundo plano. Dessa forma, você não precisaria se lembrar de iniciá-lo em segundo plano explicitamente:

    #!/bin/sh

    EDITOR="emacs" # or whatever

    if [ -z "${DISPLAY}" ]; then
      ${EDITOR} "$@"
    else
      ${EDITOR} "$@" &
    fi

Acima, primeiro tentamos determinar se você possui um servidor X disponível e, em seguida, apenas executa o editor em segundo plano (caso contrário, muitos editores do Unix usarão seu terminal e, nesse caso, você não deseja executar o editor como um processo em segundo plano) . Ele passará todos os argumentos para o editor de sua escolha verbatim ( "$@"), exatamente como você forneceu para o script do wrapper.

Quanto ao comando que está faltando ... De acordo com minha experiência básica, para programas GUI que não envolvem terminal, pode ser tão simples quanto o primeiro envio SIGSTOPe depois SIGCONTpara o processo em primeiro plano (usando o killcomando se você usar o shell script para implementar isso) . É claro que você precisaria executá-lo em outra janela / guia do terminal, e a dificuldade seria encontrar de forma conveniente e genérica o PID para o qual você deseja enviar o sinal. Por padrão, você pode enviar os dois sinais para todos os processos do nome fornecido (por padrão, para o seu editor favorito e permitindo o uso de PIDs como argumentos):

    #!/bin/sh

    EDITOR=emacs # whatever

    stop_cont_prog()
    {
      case "$1" in
        # begin with number is considered PID - this is not good 
        # enough to be taken seriously...
        [1-9]*) kill -SIGSTOP "$1"; kill -SIGCONT "$2";;
        *)      killall -SIGSTOP "$1"; killall -SIGCONT "$2";;
      esac
    }

    if [ -n "$1" ]; then
      for prog in "$@"; do stop_cont_prog "$1"; done
    else  
      stop_cont_prog "${EDITOR}"
    fi

Esse método me deu corretamente minhas guias de terminal depois de executar (vários) emacscomandos em segundo plano. Mas o processo emacs em execução no terminal não foi restaurado adequadamente devido ao controle de tarefas do shell ou à confusão de configurações do terminal. Portanto, esse método se beneficiaria de alguma sofisticação.

O SIGSTOPé exatamente o que enviar para o processo em primeiro plano quando você pressiona (por padrões comuns) CTRL- z. Consulte a stty -asaída

$ stty -a
speed 38400 baud; rows 50; columns 200; line = 0;
intr = ^C; [...] start = ^Q; stop = ^S; susp = ^Z; [...]
[...]

(saída abreviada) e sttypágina de manual:

   susp CHAR
          CHAR will send a terminal stop signal

Os processos interrompidos usando o SIGSTOPsinal podem ser reiniciados enviando SIGCONT. Normalmente, é a lógica de controle de tarefas do shell que envia SIGCONTe cuida de outras manipulações necessárias envolvidas fge bgcomandos que ignoramos.

FooF
fonte