Como bifurcar totalmente um comando shell que está usando o redirecionamento

13

Escrevi vários scripts de shell ao longo dos anos (mas certamente não sou um administrador de sistemas) e há algo que sempre me causou problemas: como posso bifurcar um comando de shell imune a interrupções em segundo plano de um script do Bash ?

Por exemplo, se eu tiver isso:

command_which_takes_time input > output

Como posso "nohup" e bifurcar isso?

O seguinte não parece fazer o que eu quero:

nohup command_which_takes_time input > output &

Qual é a sintaxe que estou procurando e o que não estou entendendo?

Cedric Martin
fonte

Respostas:

13

Tente criar subshell com (...):

( command_which_takes_time input > output ) &

Exemplo:

~$ ( (sleep 10; date) > /tmp/q ) &
[1] 19521
~$ cat /tmp/q # ENTER
~$ cat /tmp/q # ENTER
(...) #AFTER 10 seconds
~$ cat /tmp/q #ENTER
Wed Jan 11 01:35:55 CET 2012
[1]+  Done                    ( ( sleep 10; date ) > /tmp/q )
Grzegorz Wierzowiecki
fonte
18

Você deveria tentar setsid(1). Use-o como você usaria nohup:

setsid command_which_takes_time input > output

Isso (de acordo com a página de setsid(2)manual), faz a fork(2), um _exit(2)do processo pai e, em seguida, o processo filho chama setsid(2)para criar um novo grupo de processos (sessão).

Você não pode matar isso efetuando logout, e isso não faz parte do controle de tarefas do Bash. Para todos os efeitos, é um daemon adequado.

Alexios
fonte
4

existe o disowncomando bash builtin:

[1] 9180
root@ntb1:~# jobs
[1]+  Running                 sleep 120 &
root@ntb1:~# disown
root@ntb1:~# jobs
... no jobs, disowned
root@ntb1:~# ps aux | grep sleep | grep -v grep
root      9180  0.0  0.0   4224   284 pts/0    S    17:55   0:00 sleep 120
... but the sleep still runing
root@ntb1:~#

Após a renúncia , o trabalho é renegado do seu shell (para que você possa fazer logout) e ainda permanece em execução até terminar.

Veja o 1º jobscomando listado, no sleepentanto, o 2º jobsapós o repúdio não ocorreu. Mas, usando o ps, podemos ver que o trabalho ainda está sendo executado.

Daniel Péder
fonte
2

Freebsd:

/usr/sbin/daemon -f <command> <command args>
h0tw1r3
fonte
-2

Isso funcionará (não digite espaços extras):

command &>output.file
David
fonte
1
Isso parece não ter nada a ver com a pergunta, porque não bifurca ou atinge o equivalente a nohup.
Dan Getz