Estou usando '&': por que o processo não está sendo executado em segundo plano?

20

Eu sei que posso acrescentar & a um comando para executar o processo em segundo plano.

Estou pondo o SSH em uma caixa do Ubuntu 12.04 e executando um programa python com $python program.py & - mas quando eu vou fechar a janela do terminal eu recebo uma mensagem dizendo que fechar o terminal matará o processo em execução.

Por que isso? Eu estou usando o e comercial para executar o processo em segundo plano. Como posso executá-lo independentemente de eu ser SSH?

    
por bernie2436 06.06.2014 / 23:30

5 respostas

46

Quando você fecha uma janela de terminal, o emulador de terminal envia um SIGHUP para o processo que está executando, seu shell. Seu shell então encaminha esse SIGHUP para tudo que está sendo executado. No seu sistema local, este é o ssh. O ssh então encaminha o SIGHUP para o que ele está executando, o shell remoto. Então, seu shell remoto envia um SIGHUP para todos os seus processos, seu programa de segundo plano.

Existem 2 maneiras de contornar isso.

  1. Desassocie o programa em segundo plano do seu shell.
    1. Use o comando disown depois de aplicar o processo em segundo plano. Isso fará com que a concha se esqueça disso.
    2. Prefixe seu comando com nohup ( nohup $python program.py & ). Isso realiza a mesma coisa, mas usando um processo intermediário. Basicamente, ele ignora o sinal SIGHUP e, em seguida, bifurca-se & executa seu programa que herda a configuração e, em seguida, sai. Por causa do bifurcação, o programa que está sendo lançado não é filho do shell, e o shell não sabe disso. E a menos que ele instale um manipulador de sinal para SIGHUP, ele mantém a ação de ignorar de qualquer maneira.
  2. Use logout em vez de fechar a janela do terminal. Quando você usa logout , isso não é um SIGHUP e, portanto, o shell não envia um SIGHUP para nenhum de seus filhos.

Além disso, você deve certificar-se de que seu programa não grave no terminal através de STDOUT ou STDERR, já que ambos não existirão mais quando o terminal sair. Se você não os redirecionar para algo como /dev/null , o programa ainda será executado, mas se tentar gravar neles, ele obterá um SIGPIPE, e a ação padrão do SIGPIPE é matar o processo). / p>     

por 06.06.2014 / 23:58
11

O processo está sendo executado em segundo plano no terminal, mas a saída de stdout (e stderr ) ainda está sendo enviada para o terminal. Para parar isso, adicione > /dev/null 2>&1 antes do & redirecionar ambas as saídas para /dev/null - adicionar disown também garante que o processo não seja eliminado após você fechar o terminal:

COMMAND > /dev/null 2>&1 & disown

No seu caso, isso seria:

python program.py > /dev/null 2>&1 & disown
    
por 06.06.2014 / 23:49
1

Quando você faz logout, os processos em segundo plano associados à sessão de login são normalmente eliminados também. Se você quiser que eles sejam desconectados da sessão, execute-os com nohup .

nohup python program.py &
    
por 06.06.2014 / 23:37
1

O operador & separa os comandos para serem executados em paralelo, assim como ; separa os comandos para serem executados em série. Ambos os tipos de comandos ainda serão executados como um filho do processo de shell .

Então, quando você fechar o shell que iniciou esses filhos, os filhos também serão fechados.

O que você parece querer é um processo daemon , que é significativamente mais complicado porque precisa dissociar-se inteiramente do processo pai. O shell geralmente não tem uma maneira simples de fazer isso.

    
por 07.06.2014 / 05:28
1

Após o comando terminar com oe comercial ( & ), no prompt de comando, execute o comando bg :

bash> python program.py &  
bash> bg  

Isso colocará o "&" comando para o fundo

bash> jobs  

Isso listará as tarefas em execução em segundo plano

bash> fg 1   

Isso trará o Job # 1 para o primeiro plano

Outra forma, (para poder sair)

bash> at now  
bash> /full/path/python /full/path/program.py  
bash> ^d   '(# That is, Control-D, to run the command, Control-C to cancel)'  

Várias linhas podem ser submetidas ao comando at , antes do ^ d (Control-D)
veja man at .

    
por 23.03.2016 / 02:52