Wie man einen Shell-Befehl, der eine Umleitung verwendet, vollständig ausgibt

13

Ich habe im Laufe der Jahre eine ganze Reihe von Shell-Skripten geschrieben (aber ich bin sicherlich kein Sysadmin), und es gab etwas, das mich immer wieder in Schwierigkeiten brachte: Wie kann ich einen Shell-Befehl ausgeben, der von einem Bash- Skript aus immun gegen Abstürze im Hintergrund ist ?

Zum Beispiel, wenn ich das habe:

command_which_takes_time input > output

Wie kann ich das "nohup" und gabeln?

Folgendes scheint nicht zu tun, was ich will:

nohup command_which_takes_time input > output &

Nach welcher Syntax suche ich und was verstehe ich nicht?

Cedric Martin
quelle

Antworten:

13

Versuchen Sie, eine Unterschale zu erstellen mit (...):

( command_which_takes_time input > output ) &

Beispiel:

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

Du solltest es versuchen setsid(1). Verwenden Sie es so, wie Sie es verwenden würden nohup:

setsid command_which_takes_time input > output

Auf diese Weise wird (wie in der setsid(2)Manpage beschrieben) fork(2)ein _exit(2)übergeordneter Prozess ausgeführt, und der untergeordnete Prozess ruft setsid(2)auf, um eine neue Prozessgruppe (Sitzung) zu erstellen.

Sie können das nicht töten, indem Sie sich abmelden, und es ist nicht Teil der Bash-Job-Kontrolle, die sie durcheinander bringt. In jeder Hinsicht ist es ein richtiger Daemon.

Alexios
quelle
4

Es gibt einen disowneingebauten Bash-Befehl:

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

Nach der Deaktivierung wird der Job von Ihrer Shell abgelehnt (sodass Sie sich sogar abmelden können) und läuft weiter, bis er abgeschlossen ist.

Siehe den 1. jobsBefehl, der aufgeführt ist, der sleep2. jobsnach dem Verstummen jedoch nicht. Anhand der können pswir aber sehen, dass der Job noch läuft.

Daniel Péder
quelle
2

Freebsd:

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

Dies funktioniert (geben Sie keine zusätzlichen Leerzeichen ein):

command &>output.file
David
quelle
1
Dies scheint nichts mit der Frage zu tun zu haben, da es nicht das Äquivalent von gabelt oder erreicht nohup.
Dan Getz