Como faço para colocar um processo já em execução sob nohup?
Pergunta
Eu tenho um processo que já está em execução por um longo tempo e não quero acabar com ela.
Como faço para colocá-lo sob nohup (isto é, como faço para fazer com que ele continue rodando mesmo se eu fechar o terminal?)
Solução
Usando o Job Control do bash para enviar o processo para o background:
- Ctrl + Z para parar (pausa) o programa e voltar para o shell.
-
bg
para executá-lo em segundo plano. -
disown -h [job-spec]
onde [trabalho-spec] é o número de trabalho (como%1
para o primeiro emprego em execução; encontrar sobre o seu número com o comandojobs
). De modo que o trabalho não está morto quando o fecha terminais
Outras dicas
Suponha que, por algum motivo Ctrl + Z , também não está funcionando, ir para outro terminal, encontrar o ID do processo (usando ps
) e execute:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP
irá suspender o processo e SIGCONT
vai retomar o processo, no fundo. Então, agora, fechando ambos os seus terminais não vai parar seu processo.
O comando para separar um trabalho em execução a partir do shell (= torna nohup) é disown
e um shell de comando básico.
De bash-manpage (homem bash):
disown [-ar] [-h] [jobspec ...]
Sem opções, cada jobspec é removida da mesa de trabalhos ativos. Se a opção-h é dada, cada jobspec não é removida da tabela, mas é marcada para que SIGHUP não é enviado para o trabalho, se o shell recebe um SIGHUP. Se nenhum jobspec é presente, e nem o -a nem a opção -r é fornecido, o trabalho atual é usado. Se nenhum jobspec é fornecido, a opção -a meios para remover ou marcar todos os postos de trabalho; a opção -r, sem um argumento jobspec restringe operação para executar trabalhos. O retorno valor é 0 a menos que um jobspec não especificar um trabalho válido.
Isso significa, que uma simples
disown -a
irá remover todos os trabalhos de-table trabalho a e torna nohup
Estas são boas respostas acima, eu só queria acrescentar um esclarecimento:
Você não pode disown
um pid ou processo, você disown
um emprego, e que é uma distinção importante.
Um trabalho é algo que é uma noção de um processo que está ligado a uma concha, portanto, você tem que jogar o trabalho em segundo plano (não suspendê-lo) e, em seguida, ignora isso.
Issue:
% jobs
[1] running java
[2] suspended vi
% disown %1
http://www.quantprinciple.com/ investir / index.php / docs / tipsandtricks / unix / jobcontrol / para uma discussão mais detalhada de Controle do trabalho Unix.
Infelizmente disown
é específico para o bash e não está disponível em todas as conchas.
Certos tipos de Unix (por exemplo AIX e Solaris) ter uma opção no próprio comando nohup
que pode ser aplicada a um processo de execução:
nohup -p pid
Consulte http://en.wikipedia.org/wiki/Nohup
A resposta de Node é realmente grande, mas deixou em aberto a questão de como pode obter stdout e stderr redirecionado. Eu encontrei uma solução em Unix e Linux , mas também não é completa. Gostaria de mesclar essas duas soluções. Aqui está:
Para o meu teste eu fiz um script pequeno chamado loop.sh, que imprime o pid de si mesmo com um sono minutos em um loop infinito.
$./loop.sh
Agora obter a PID do processo de alguma forma. Normalmente ps -C loop.sh
é bom o suficiente, mas é impresso no meu caso.
Agora podemos mudar para outro terminal (ou pressione ^ Z e no mesmo terminal). Agora gdb
deve ser anexado a este processo.
$ gdb -p <PID>
Isso interrompe o script (se executado). Seu estado pode ser verificado ps -f <PID>
, onde o campo STAT
é 'T +' (ou em caso de ^ Z 'T'), que significa (homem ps (1))
T Stopped, either by a job control signal or because it is being traced
+ is in the foreground process group
(gdb) call close(1)
$1 = 0
Fechar (1) retorna zero em caso de sucesso.
(gdb) call open("loop.out", 01102, 0600)
$6 = 1
Open (1) retorna o novo descritor de arquivo, se bem sucedido.
Este aberta é igual a open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
.
Em vez de O_RDWR
O_WRONLY
poderia ser aplicada, mas /usr/sbin/lsof
diz 'u' para todos std * manipuladores de arquivos (coluna FD
), que é O_RDWR
.
Eu verifiquei os valores em /usr/include/bits/fcntl.h arquivo de cabeçalho.
O arquivo de saída pode ser aberto com O_APPEND
, como nohup
faria, mas isso não é sugerido por man open(2)
, por causa de problemas possíveis NFS.
Se conseguirmos -1 como um valor de retorno, cópias, em seguida, call perror("")
a mensagem de erro. Se precisamos do errno, uso p errno
gdb comand.
Agora podemos verificar o arquivo recém redirecionado. impressões /usr/sbin/lsof -p <PID>
:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
Se quisermos, podemos redirecionar stderr para outro arquivo, se quisermos usar call close(2)
e call open(...)
novamente usando um nome de arquivo diferente.
Agora, o bash
anexado tem de ser lançado e podemos sair gdb
:
(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q
Se o script foi parado por gdb
de um outro terminal que continua a funcionar. Podemos voltar para o terminal de loop.sh. Agora não escrever nada para a tela, mas correndo e escrever no arquivo. Temos que colocá-lo em segundo plano. Assim imprensa ^Z
.
^Z
[1]+ Stopped ./loop.sh
(Agora estamos no mesmo estado como se ^Z
foi pressionado no início.)
Agora podemos verificar o estado do trabalho:
$ ps -f 24522
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
$ jobs
[1]+ Stopped ./loop.sh
processo Então deve ser executado em segundo plano e desligado do terminal. O número na saída do comando jobs
entre colchetes identifica o trabalho interno bash
. Podemos usar na seguinte construído em comandos bash
aplicando um sinal '%' antes do número do trabalho:
$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
E agora podemos sair da festa chamando. O processo continua em execução em segundo plano. Se parar seu PPID se tornar 1 ((1) processo init) e do terminal de controle desconhecido se tornar.
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID> 1 0 11:16 ? S 0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey 0u CHR 136,36 38 /dev/pts/36 (deleted)
loop.sh <PID> truey 1u REG 0,26 1127 15008411 /home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,36 38 /dev/pts/36 (deleted)
COMENTÁRIO
O material gdb pode ser automatizado criação de um arquivo (por exemplo loop.gdb) contendo os comandos e gdb -q -x loop.gdb -p <PID>
prazo. Meus loop.gdb esta aparência:
call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit
Ou pode-se usar o forro seguinte em vez disso:
gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
Espero que esta é uma descrição bastante completa da solução.
Para enviar processo em execução para nohup ( http://en.wikipedia.org/wiki/Nohup)
nohup -p pid
, ele não funcionou para mim
Então eu tentei os seguintes comandos e funcionou muito fina
-
Executar alguns alguma_coisa, dizer
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
. -
Ctrl + Z para parar (pausa) o programa e voltar para o shell.
-
bg
para executá-lo em segundo plano. -
disown -h
para que o processo não está morto quando o fecha terminais. -
Tipo
exit
para sair da casca, porque agora você está pronto para ir como a operação será executado em segundo plano no seu próprio processo, por isso não está amarrado a um shell.
Este processo é o equivalente a executar nohup SOMECOMMAND
.
No meu sistema AIX, eu tentei
nohup -p processid>
Isso funcionou bem. Ele continuou a executar o meu processo mesmo depois de fechar janelas de terminal. Temos ksh como shell padrão para os comandos bg
e disown
não funcionou.
- Ctrl + z - isto irá pausar o trabalho (! Não indo para cancelar)
-
bg
- isso vai colocar o trabalho no fundo e retornar no processo em execução -
disown -a
- o que irá cortar todo o anexo com trabalho (assim você pode fechar o terminal e ainda será executado)
Estes passos simples permitirá que você fechar o terminal, enquanto processo de manter em execução.
Não vai colocar em nohup
(com base na minha compreensão da sua pergunta, você não precisa dele aqui).
Isso funcionou para mim no Ubuntu Linux, enquanto em tcshell.
-
Ctrl Z para pausá-lo
-
bg
para ser executado no fundo -
jobs
para obter o seu número de trabalho -
nohup %n
onde n é o número de trabalho