Comment totalement fork une commande shell qui utilise la redirection

13

J'ai écrit pas mal de scripts shell au fil des ans (mais je ne suis certainement pas un administrateur système) et il y a quelque chose qui m'a toujours causé des problèmes: comment puis-je bifurquer une commande shell à l'abri des blocages en arrière-plan à partir d'un script Bash ?

Par exemple, si j'ai ceci:

command_which_takes_time input > output

Comment puis-je "nohup" et bifurquer cela?

Ce qui suit ne semble pas faire ce que je veux:

nohup command_which_takes_time input > output &

Quelle est la syntaxe que je recherche et que ne comprends-je pas?

Cedric Martin
la source

Réponses:

13

Essayez de créer un sous-shell avec (...):

( command_which_takes_time input > output ) &

Exemple:

~$ ( (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
la source
18

Tu devrais essayer setsid(1). Utilisez-le comme vous le feriez nohup:

setsid command_which_takes_time input > output

Ceci (selon la setsid(2)page de manuel), fait un fork(2), un _exit(2)du processus parent, puis le processus enfant appelle setsid(2)pour créer un nouveau groupe de processus (session).

Vous ne pouvez pas tuer cela en vous déconnectant, et cela ne fait pas partie du shebang de contrôle du travail Bash. À toutes fins utiles, c'est un démon approprié.

Alexios
la source
4

il y a la disowncommande bash intégrée:

[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:~#

Après l'avoir désavoué , le travail est désavoué de votre shell (vous pouvez même vous déconnecter) et il reste en cours d'exécution jusqu'à la fin.

Voir la 1ère jobscommande listée sleepmais la 2ème jobsaprès le reniement non. Mais en utilisant le, psnous pouvons voir que le travail est toujours en cours d'exécution.

Daniel Péder
la source
2

Freebsd:

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

Cela fonctionnera (ne saisissez aucun espace supplémentaire):

command &>output.file
David
la source
1
Cela semble n'avoir rien à voir avec la question, car elle ne se déroule pas ou n'atteint pas l'équivalent de nohup.
Dan Getz