Às vezes, quero iniciar um processo e esquecê-lo. Se eu iniciá-lo na linha de comando, assim:
redshift
Não consigo fechar o terminal ou isso acabará com o processo. Posso executar um comando para fechar o terminal sem interromper o processo?
Um dos 2 a seguir deve funcionar:
$ Nohup redshift &
ou
$ redshift &
$ disown
Veja o seguinte para obter mais informações sobre como isso funciona:
man Nohup
help disown
Diferença entre Nohup, renegado e & (não deixe de ler também os comentários)
Se o seu programa estiver já em execução, você poderá pausá-lo com Ctrl-Z
, puxe-o para segundo plano com bg
e depois disown
, desta forma:
$ sleep 1000
^Z
[1]+ Stopped sleep 1000
$ bg
$ disown
$ exit
Boa resposta já foi publicada por @StevenD, mas acho que isso pode esclarecer um pouco mais.
O motivo pelo qual o processo é interrompido na finalização do terminal é que o processo iniciado é um processo filho do terminal. Depois de fechar o terminal, isso também matará esses processos filhos. Você pode ver a árvore de processos com pstree
, por exemplo, ao executar kate &
no Konsole:
init-+
├─konsole─┬─bash─┬─kate───2*[{kate}]
│ │ └─pstree
│ └─2*[{konsole}]
Para tornar o processo kate
desanexado de konsole
quando você terminar konsole
, use Nohup
com o comando, desta forma:
Nohup kate &
Após fechar konsole
, pstree
terá a seguinte aparência:
init-+
|-kate---2*[{kate}]
e kate
sobreviverão. :)
Uma alternativa é usar screen
/tmux
/byobu
, o que manterá o Shell em execução, independente do terminal.
Você pode executar o processo como este no terminal
setsid process
Isso executará o programa em uma nova sessão. Conforme explicado http://hanoo.org/index.php?article=run-program-in-new-session-linux
Embora todas as sugestões funcionem bem, descobri que minha alternativa é usar screen
, um programa que configura um terminal virtual na tela.
Você pode considerar iniciá-lo com screen -S session_name
. A tela pode ser instalada em praticamente todos os derivados Linux e Unix. Batendo Ctrl+A e (minúscula) C iniciará uma segunda sessão. Isso permitiria alternar entre a sessão inicial pressionando Ctrl+A e ou a sessão mais recente pressionando Ctrl+A e 1. Você pode ter até dez sessões em um terminal. Eu costumava iniciar uma sessão no trabalho, ir para casa, fazer ssh na minha máquina de trabalho e depois invocar screen -d -R session_name
. Isso irá reconectá-lo a essa sessão remota.
Eu prefiro:
(Nome do aplicativo e)
por exemplo: [email protected]:~$ (chromium-browser &)
Certifique-se de usar parênteses ao digitar o comando!
Eu tenho um script para:
Eu o uso principalmente para gedit
, evince
, inkscape
etc, que possuem muitas saídas irritantes de terminal. Se o comando terminar antes de TIMEOUT
, o status de saída do Nohup será retornado em vez de zero.
#!/bin/bash
TIMEOUT=0.1
#use Nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send Nohup's output to /dev/null, supressing Nohup.out
#run Nohup in the background so this script doesn't block
Nohup "${@}" >/dev/null 2>&1 &
Nohup_PID=$!
#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally
#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $Nohup_PID
Nohup_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[ $Nohup_STATUS != 0 ] && echo "Error ${@}"
#return the exit status of Nohup, whatever it was
exit $Nohup_STATUS
exemplos...
>>> run true && echo success || echo fail
success
>>> run false && echo success || echo fail
Error false
fail
>>> run sleep 1000 && echo success || echo fail
success
>>> run notfound && echo success || echo fail
Error notfound
fail
A maneira exclusiva do Shell de fazer tudo isso é fechar o stdin e colocar em segundo plano o comando:
command <&- &
Então não será encerrado quando você sair do Shell. Redirecionar stdout é uma boa opção opcional.
A desvantagem é que você não pode fazer isso depois do fato.
Você pode definir um processo (PID) para não receber um sinal HUP ao sair e fechar a sessão do terminal. Use o seguinte comando:
Nohup -p PID
Indiscutivelmente semelhante ao resposta oferecida por apolinsky , eu uso uma variante em screen
. O comando Vanilla é assim
screen bash -c 'long_running_command_here; echo; read -p "ALL DONE:"'
A sessão pode ser desconectada com Ctrl ACtrl D e reconectado no caso simples com screen -r
. Eu tenho isso envolto em um script chamado session
que mora no meu PATH
pronto para acesso conveniente:
#!/bin/bash
#
if screen -ls | awk '$1 ~ /^[1-9][0-9]*\.'"$1"'/' >/dev/null
then
echo "WARNING: session is already running (reattach with 'screen -r $1')" >&2
else
exec screen -S "$1" bash -c "[email protected]; echo; echo '--------------------'; read -p 'ALL DONE (Enter to exit):'"
echo "ERROR: 'screen' is not installed on this system" >&2
fi
exit 1
Isso só funciona quando você sabe com antecedência que deseja desconectar um programa. Ele não prevê que um programa já esteja em execução seja desconectado.
Da mesma forma que outras respostas postadas anteriormente, pode-se transferir um processo em execução para usar a "tela" retrospectivamente, graças a reptyr e depois fechar o terminal. As etapas são descritas neste post . Os passos a seguir são: