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?)

Foi útil?

Solução

Usando o Job Control do bash para enviar o processo para o background:

  1. Ctrl + Z para parar (pausa) o programa e voltar para o shell.
  2. bg para executá-lo em segundo plano.
  3. 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 comando jobs). 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

  1. Executar alguns alguma_coisa, dizer /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Ctrl + Z para parar (pausa) o programa e voltar para o shell.

  3. bg para executá-lo em segundo plano.

  4. disown -h para que o processo não está morto quando o fecha terminais.

  5. 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.

  1. Ctrl + z - isto irá pausar o trabalho (! Não indo para cancelar)
  2. bg - isso vai colocar o trabalho no fundo e retornar no processo em execução
  3. 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.

  1. Ctrl Z para pausá-lo

  2. bg para ser executado no fundo

  3. jobs para obter o seu número de trabalho

  4. nohup %n onde n é o número de trabalho

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top