Para quem enfrenta o mesmo problema: lembre-se de que, mesmo que você digite yourExecutable &e as saídas continuem aparecendo na tela e Ctrl+Cnão pare nada, basta digitar cegamente disown;e pressionar Entermesmo que a tela esteja rolando com saídas e você não possa ver o que você está digitando. O processo será contestado e você poderá fechar o terminal sem que o processo acabe.
Nav
Respostas:
1367
Usando o Job Control do bash para enviar o processo para o segundo plano:
Ctrl+ Zpara parar (pausar) o programa e voltar ao shell.
bg para executá-lo em segundo plano.
disown -h [job-spec]onde [job-spec] é o número do trabalho (como %1no primeiro trabalho em execução; encontre o seu número com o jobscomando) para que o trabalho não seja eliminado quando o terminal for fechado.
Como a questão era como "colocá-lo em nohup", disown -htalvez seja a resposta mais exata: "fazer com que o renomado se comporte mais como nohup (ou seja, os trabalhos permanecerão na árvore de processos do shell atual até você sair do shell)" Isso permite que você veja todos os trabalhos que esse shell iniciou ". (de [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )
Dr. Jan-Philip Gehrcke
8
Como recupero o trabalho mais tarde? Eu posso vê-lo rodando usando ps -e.
Paulo Casaretto
26
Você não pode ver a saída de um trabalho depois que a disown, disown torna um processo um daemon, o que significa que a entrada / saída padrão é redirecionada para / dev / null. Então, se você pretende renegar um trabalho, é melhor começar com login em um arquivo, por exemplomy_job_command | tee my_job.log
rustyx
8
é possível de alguma forma fazer algo como 'my_job_command | tee my_job.log ' depois que o comando já estiver em execução?
Arod #
23
disowndesassocia quaisquer tubos do processo. Para recolocar os tubos, use gdbcomo descrito neste tópico . Mais especificamente, este post .
Mbrownnyc
185
Suponha que, por algum motivo, o Ctrl+ Ztambém não esteja funcionando, vá para outro terminal, encontre o ID do processo (usando ps) e execute:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOPsuspenderá o processo e SIGCONTretomará o processo em segundo plano. Portanto, agora, fechar os dois terminais não interromperá o processo.
Sim, isso é um problema do sistema operacional, o kill não funciona com o Cygwin no Windows.
Pungs
6
Também é muito útil se o trabalho for iniciado a partir de outra sessão ssh.
Amir Ali Akbari
5
Lembre-se de fazer disown %1o primeiro terminal antes de fechá-lo.
fred
1
Isso é útil desde que iniciei uma interface gráfica com um console (no meu caso, iniciei no konsole kwinapós uma falha sem pensar nas consequências). Então, se eu parasse o kwin, tudo teria congelado e eu não tinha possibilidade de correr bg!
Michele
@fred Eu não fiz isso e parecia continuar funcionando. Possível ou atingi o PID errado?
219166 Ninguém escreveu:
91
O comando para separar um trabalho em execução do shell (= torna nohup) é disowne um comando shell básico.
De bash-manpage (man bash):
renegar [-ar] [-h] [jobspec ...]
Sem opções, cada especificação de trabalho é removida da tabela de tarefas ativas. Se a opção -h for fornecida, cada jobpec não será removido da tabela, mas será marcado para que SIGHUP não seja enviado para o job se o shell receber um SIGHUP. Se nenhuma especificação de trabalho estiver presente e nem a opção -a nem a -r forem fornecidas, a tarefa atual será usada. Se nenhuma especificação de trabalho for fornecida, a opção -a significa remover ou marcar todas as tarefas; a opção -r sem um argumento jobspec restringe a operação à execução de jobs. O valor de retorno é 0, a menos que um jobpec não especifique um trabalho válido.
Isso significa que um simples
disown -a
removerá todos os trabalhos da tabela de trabalhos e os tornará nohup
disown -aremove todos os trabalhos. Um simples disownremove apenas o trabalho atual. Como a página de manual na resposta diz.
Rune Schjellerup Philosof
73
Estas são boas respostas acima, eu só queria adicionar um esclarecimento:
Você não pode dar disownum pid ou processo, disownum emprego, e essa é uma distinção importante.
Um trabalho é algo que é uma noção de um processo anexado a um shell; portanto, você deve lançar o trabalho em segundo plano (não suspendê-lo) e depois rejeitá-lo.
Questão:
% jobs
[1] running java
[2] suspended vi
% disown %1
Somente para AIXe Solaris. "As versões AIX e Solaris do nohup têm uma opção -p que modifica um processo em execução para ignorar futuros sinais SIGHUP. Diferentemente do built-in desown acima descrito, o nohup -p aceita IDs de processo.". Fonte
AlikElzin-kilaka
27
A resposta do nó é realmente ótima, mas deixou em aberto a questão de como o stdout e o stderr podem ser redirecionados. Encontrei uma solução em Unix e Linux , mas também não está completa. Gostaria de mesclar essas duas soluções. Aqui está:
Para o meu teste, criei um pequeno script bash chamado loop.sh, que imprime o pid de si mesmo com um minuto de sono em um loop infinito.
$./loop.sh
Agora obtenha o PID desse processo de alguma forma. Geralmente ps -C loop.shé bom o suficiente, mas é impresso no meu caso.
Agora podemos mudar para outro terminal (ou pressionar ^ Z e no mesmo terminal). Agora gdbdeve ser anexado a esse processo.
$ gdb -p <PID>
Isso interrompe o script (se estiver em execução). Seu estado pode ser verificado por ps -f <PID>, onde o STATcampo é 'T +' (ou no caso de ^ Z 'T'), o que significa (man 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
Aberto (1) retorna o novo descritor de arquivo, se for bem-sucedido.
Esta abertura é igual a open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). Em vez de O_RDWRO_WRONLYpoderia ser aplicado, mas /usr/sbin/lsofdiz 'u' para todos os manipuladores de arquivos std * ( FDcoluna), o que é O_RDWR.
Eu verifiquei os valores no arquivo de cabeçalho /usr/include/bits/fcntl.h.
O arquivo de saída pode ser aberto com O_APPEND, como nohupfaria, mas isso não é sugerido por man open(2)causa de possíveis problemas no NFS.
Se obtivermos -1 como valor de retorno, call perror("")imprima a mensagem de erro. Se precisarmos do errno, use o p errnocomando gdb.
Agora podemos verificar o arquivo recém-redirecionado. /usr/sbin/lsof -p <PID>impressões:
Se quisermos, podemos redirecionar o stderr para outro arquivo, se quisermos usar call close(2)e call open(...)novamente usando um nome de arquivo diferente.
Agora o anexo bashprecisa ser liberado e podemos sair gdb:
(gdb) detach
Detaching from program:/bin/bash, process <PID>(gdb) q
Se o script foi parado por gdboutro terminal, ele continua sendo executado. Podemos voltar ao terminal loop.sh. Agora, ele não grava nada na tela, mas executa e grava no arquivo. Temos que colocá-lo em segundo plano. Então pressione ^Z.
^Z
[1]+Stopped./loop.sh
(Agora estamos no mesmo estado em que ^Zfoi 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>011:16 pts/36 S 0:00/bin/bash ./loop.sh
$ jobs
[1]+Stopped./loop.sh
Portanto, o processo deve estar em execução em segundo plano e desconectado do terminal. O número na jobssaída do comando entre colchetes identifica o trabalho dentro bash. Podemos usar os seguintes bashcomandos internos, 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>011:16 pts/36 S 0:00/bin/bash ./loop.sh
E agora podemos sair da festança de chamadas. O processo continua em execução em segundo plano. Se sairmos do seu PPID, tornar-se 1 (processo init (1)) e o terminal de controle se tornar desconhecido.
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID><PID>1011:16? S 0:00/bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>...
loop.sh <PID> truey 0u CHR 136,3638/dev/pts/36(deleted)
loop.sh <PID> truey 1u REG 0,26112715008411/home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,3638/dev/pts/36(deleted)
COMENTE
O material gdb pode ser automatizado, criando um arquivo (por exemplo, loop.gdb) contendo os comandos e executado gdb -q -x loop.gdb -p <PID>. Meu loop.gdb fica assim:
Muito informativo e provavelmente funcionará bem em casos simples. Mas esteja avisado, casos mais complexos podem falhar miseravelmente. Eu tinha um desses hoje: meu processo gerou outro processo que produziu a saída (presumivelmente para stderr), mas que stdout se conectou à comunicação com seu mestre. Redirecionar os DFs mestres não teve efeito porque a criança herdou o stderr e o fechamento do stdout da criança falhou com o mestre que estava esperando na outra extremidade do tubo. X- A Bettern conhece bem seus processos antes de tentar isso.
cmaster - reinstate monica
@cmaster Você pode verificar se um identificador é redirecionado usando lsof(o nome do identificador de arquivo pipenão é igual a /dev/pts/1) ou por ls -l /proc/<PID>/fd/<fd>(isso mostra o link simbólico do identificador). Além disso, os subprocessos ainda não podem ter saídas redirecionadas, que devem ser redirecionadas para um arquivo.
Então eu tentei os seguintes comandos e funcionou muito bem
Execute alguns SOMECOMMAND, digamos /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.
Ctrl+ Zpara parar (pausar) o programa e voltar ao shell.
bg para executá-lo em segundo plano.
disown -h para que o processo não seja interrompido quando o terminal fechar.
Digite exitpara sair do shell, porque agora você pode prosseguir, pois a operação será executada em segundo plano em seu próprio processo, para que não esteja vinculada a um shell.
Esse processo é equivalente à execução nohup SOMECOMMAND.
Isso funcionou bem. Ele continuou a executar o meu processo, mesmo depois de fechar as janelas do terminal. Nós temos o ksh como shell padrão para que os comandos bge disownnão funcionem.
Penso que o comportamento de renegar -a é cortar o apego em todos os trabalhos. No entanto, ele não desligamento dos dutos stdin / stdout, o que significa que o processo ainda vai tentar escrever (/ Read) a partir do terminal
Kelthar
-2
Isso funcionou para mim no Ubuntu linux enquanto estava no tcshell.
yourExecutable &
e as saídas continuem aparecendo na tela eCtrl+C
não pare nada, basta digitar cegamentedisown;
e pressionarEnter
mesmo que a tela esteja rolando com saídas e você não possa ver o que você está digitando. O processo será contestado e você poderá fechar o terminal sem que o processo acabe.Respostas:
Usando o Job Control do bash para enviar o processo para o segundo plano:
bg
para executá-lo em segundo plano.disown -h [job-spec]
onde [job-spec] é o número do trabalho (como%1
no primeiro trabalho em execução; encontre o seu número com ojobs
comando) para que o trabalho não seja eliminado quando o terminal for fechado.fonte
disown -h
talvez seja a resposta mais exata: "fazer com que o renomado se comporte mais como nohup (ou seja, os trabalhos permanecerão na árvore de processos do shell atual até você sair do shell)" Isso permite que você veja todos os trabalhos que esse shell iniciou ". (de [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )disown
, disown torna um processo um daemon, o que significa que a entrada / saída padrão é redirecionada para / dev / null. Então, se você pretende renegar um trabalho, é melhor começar com login em um arquivo, por exemplomy_job_command | tee my_job.log
disown
desassocia quaisquer tubos do processo. Para recolocar os tubos, usegdb
como descrito neste tópico . Mais especificamente, este post .Suponha que, por algum motivo, o Ctrl+ Ztambém não esteja funcionando, vá para outro terminal, encontre o ID do processo (usando
ps
) e execute:SIGSTOP
suspenderá o processo eSIGCONT
retomará o processo em segundo plano. Portanto, agora, fechar os dois terminais não interromperá o processo.fonte
disown %1
o primeiro terminal antes de fechá-lo.kwin
após uma falha sem pensar nas consequências). Então, se eu parasse o kwin, tudo teria congelado e eu não tinha possibilidade de correrbg
!O comando para separar um trabalho em execução do shell (= torna nohup) é
disown
e um comando shell básico.De bash-manpage (man bash):
Isso significa que um simples
removerá todos os trabalhos da tabela de trabalhos e os tornará nohup
fonte
disown -a
remove todos os trabalhos. Um simplesdisown
remove apenas o trabalho atual. Como a página de manual na resposta diz.Estas são boas respostas acima, eu só queria adicionar um esclarecimento:
Você não pode dar
disown
um pid ou processo,disown
um emprego, e essa é uma distinção importante.Um trabalho é algo que é uma noção de um processo anexado a um shell; portanto, você deve lançar o trabalho em segundo plano (não suspendê-lo) e depois rejeitá-lo.
Questão:
Veja http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ para uma discussão mais detalhada sobre o Unix Job Control.
fonte
Infelizmente,
disown
é específico do bash e não está disponível em todas as conchas.Certos tipos de Unix (por exemplo, AIX e Solaris) têm uma opção no
nohup
próprio comando que pode ser aplicada a um processo em execução:Veja http://en.wikipedia.org/wiki/Nohup
fonte
AIX
eSolaris
. "As versões AIX e Solaris do nohup têm uma opção -p que modifica um processo em execução para ignorar futuros sinais SIGHUP. Diferentemente do built-in desown acima descrito, o nohup -p aceita IDs de processo.". FonteA resposta do nó é realmente ótima, mas deixou em aberto a questão de como o stdout e o stderr podem ser redirecionados. Encontrei uma solução em Unix e Linux , mas também não está completa. Gostaria de mesclar essas duas soluções. Aqui está:
Para o meu teste, criei um pequeno script bash chamado loop.sh, que imprime o pid de si mesmo com um minuto de sono em um loop infinito.
Agora obtenha o PID desse processo de alguma forma. Geralmente
ps -C loop.sh
é bom o suficiente, mas é impresso no meu caso.Agora podemos mudar para outro terminal (ou pressionar ^ Z e no mesmo terminal). Agora
gdb
deve ser anexado a esse processo.Isso interrompe o script (se estiver em execução). Seu estado pode ser verificado por
ps -f <PID>
, onde oSTAT
campo é 'T +' (ou no caso de ^ Z 'T'), o que significa (man ps (1))Fechar (1) retorna zero em caso de sucesso.
Aberto (1) retorna o novo descritor de arquivo, se for bem-sucedido.
Esta abertura é igual a
open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
. Em vez deO_RDWR
O_WRONLY
poderia ser aplicado, mas/usr/sbin/lsof
diz 'u' para todos os manipuladores de arquivos std * (FD
coluna), o que éO_RDWR
.Eu verifiquei os valores no arquivo de cabeçalho /usr/include/bits/fcntl.h.
O arquivo de saída pode ser aberto com
O_APPEND
, comonohup
faria, mas isso não é sugerido porman open(2)
causa de possíveis problemas no NFS.Se obtivermos -1 como valor de retorno,
call perror("")
imprima a mensagem de erro. Se precisarmos do errno, use op errno
comando gdb.Agora podemos verificar o arquivo recém-redirecionado.
/usr/sbin/lsof -p <PID>
impressões:Se quisermos, podemos redirecionar o stderr para outro arquivo, se quisermos usar
call close(2)
ecall open(...)
novamente usando um nome de arquivo diferente.Agora o anexo
bash
precisa ser liberado e podemos sairgdb
:Se o script foi parado por
gdb
outro terminal, ele continua sendo executado. Podemos voltar ao terminal loop.sh. Agora, ele não grava nada na tela, mas executa e grava no arquivo. Temos que colocá-lo em segundo plano. Então pressione^Z
.(Agora estamos no mesmo estado em que
^Z
foi pressionado no início.)Agora podemos verificar o estado do trabalho:
Portanto, o processo deve estar em execução em segundo plano e desconectado do terminal. O número na
jobs
saída do comando entre colchetes identifica o trabalho dentrobash
. Podemos usar os seguintesbash
comandos internos, aplicando um sinal '%' antes do número do trabalho:E agora podemos sair da festança de chamadas. O processo continua em execução em segundo plano. Se sairmos do seu PPID, tornar-se 1 (processo init (1)) e o terminal de controle se tornar desconhecido.
COMENTE
O material gdb pode ser automatizado, criando um arquivo (por exemplo, loop.gdb) contendo os comandos e executado
gdb -q -x loop.gdb -p <PID>
. Meu loop.gdb fica assim:Ou pode-se usar o seguinte liner:
Espero que esta seja uma descrição bastante completa da solução.
fonte
lsof
(o nome do identificador de arquivopipe
não é igual a/dev/pts/1
) ou porls -l /proc/<PID>/fd/<fd>
(isso mostra o link simbólico do identificador). Além disso, os subprocessos ainda não podem ter saídas redirecionadas, que devem ser redirecionadas para um arquivo.Para enviar o processo em execução para o nohup ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid
, não funcionou para mimEntão eu tentei os seguintes comandos e funcionou muito bem
Execute alguns SOMECOMMAND, digamos
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.Ctrl+ Zpara parar (pausar) o programa e voltar ao shell.
bg
para executá-lo em segundo plano.disown -h
para que o processo não seja interrompido quando o terminal fechar.Digite
exit
para sair do shell, porque agora você pode prosseguir, pois a operação será executada em segundo plano em seu próprio processo, para que não esteja vinculada a um shell.Esse processo é equivalente à execução
nohup SOMECOMMAND
.fonte
No meu sistema AIX, tentei
Isso funcionou bem. Ele continuou a executar o meu processo, mesmo depois de fechar as janelas do terminal. Nós temos o ksh como shell padrão para que os comandos
bg
edisown
não funcionem.fonte
bg
- isso colocará o trabalho em segundo plano e retornará ao processo em execuçãodisown -a
- isso cortará todo o anexo com o trabalho (para que você possa fechar o terminal e ele ainda funcione)Essas etapas simples permitirão fechar o terminal enquanto mantém o processo em execução.
Ele não será colocado
nohup
(com base no meu entendimento da sua pergunta, você não precisa dela aqui).fonte
Isso funcionou para mim no Ubuntu linux enquanto estava no tcshell.
CtrlZ pausar
bg
executar em segundo planojobs
para obter o número do trabalhonohup %n
onde n é o número do trabalhofonte
nohup: failed to run command '%1': No such file or directory