ubuntuusers.de

nohup wird im Hintergrund beendet

Status: Gelöst | Ubuntu-Version: Server 14.10 (Utopic Unicorn)
Antworten |

root213123

Anmeldungsdatum:
21. Januar 2014

Beiträge: 130

Der folgende Befehl wird ordnungsgemäß ausgeführt:

1
nohup tail -f test.txt &

Mit "Enter" wird der Befehl in den Hintergrund versetzt und ich kann auf der Command-Line weiterarbeiten. Sobald ich aus irgendeinem Grund "^C" ( Ctrl+C ) drücke, beendet sich nicht nur der aktuelle Befehl, sondern auch der im Hintergrund. Auf meinem anderen Linux tritt dieses Problem komischerweise nicht auf. Auch wenn ich das Terminal schließe, wird er beendet. Wie kann ich den Prozess komplett übergeben, sodass mein Terminal nichts mehr mit dem Befehl zu tun hat?

Danke für die Hilfe!

lubux

Anmeldungsdatum:
21. November 2012

Beiträge: 14388

root213123 schrieb:

Der folgende Befehl wird ordnungsgemäß ausgeführt:

nohup tail -f test.txt &

tail mit -f benutzt man doch für eine Ausgabe am standard output. Warum willst bzw. warum musst Du "tail -f" mit nohup und & benutzen?

root213123

(Themenstarter)

Anmeldungsdatum:
21. Januar 2014

Beiträge: 130

Das war nur ein Besipiel-Command, weil mein wirklicher Command viel länger ist. Ein anderes Beispiel:

1
nohup tcpdump -i eth0 -w file.dump &

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13224

Ich vermute, dadurch, dass Dateideskriptor 1 und 2 mit dem Terminal verbunden bleiben, bleibt das Terminal das "Controlling Terminal" und das Signal vom Ctrl-C wird auch an den Hintergrundprozess gesendet. Schau Dir doch mal den Teil zu Job Control im Referenzmanual der bash an. Ggf. hilft das weiter.

Mooi

Anmeldungsdatum:
15. August 2014

Beiträge: 187

Vielleicht kann man hier screen benutzen. Das ist aber nur ein Schuss ins Blaue.

root213123

(Themenstarter)

Anmeldungsdatum:
21. Januar 2014

Beiträge: 130

Da ich einen anderen Befehl und eine andere Shell verwendet habe, kann ich meine Problemlösung nicht für den normalen Ubuntu-Nutzer empfehlen. Daher folgende Abhilfe für Bash:

1
nohup ./script 1> /dev/null 2> /dev/null < /dev/null &

Mit "< /dev/null" wird /dev/null als stdin gesetzt. Somit gelangen meine späteren Eingaben nicht in das stdin.

Trotzdem danke für die Hilfe!

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13224

root213123 schrieb:

Da ich einen anderen Befehl und eine andere Shell verwendet habe, kann ich meine Problemlösung nicht für den normalen Ubuntu-Nutzer empfehlen. Daher folgende Abhilfe für Bash:

1
nohup ./script 1> /dev/null 2> /dev/null < /dev/null &

Mit "< /dev/null" wird /dev/null als stdin gesetzt. Somit gelangen meine späteren Eingaben nicht in das stdin.

Das löst Dein Problem? Die Umleitungen dürften alle für das Kappen der Verbindung zum Terminal nichts bringen, denn die Manpage von nohup sagt:

       If  standard input is a terminal, redirect it from /dev/null.  If standard output is a terminal, append output
       to 'nohup.out' if possible, '$HOME/nohup.out' otherwise.  If standard error is  a  terminal,  redirect  it  to
       standard output.  To save output to FILE, use 'nohup COMMAND > FILE'.

(Was im Übrigen auch meine Vermutung widerlegt.)

Übrigens sagt sie auch

       NOTE:  your  shell  may  have  its  own version of nohup, which usually supersedes the version described here.
       Please refer to your shell's documentation for details about the options it supports.

Das könnte unterschiedliches Verhalten mit einer anderen (welcher?) Shell erklären.

Ich würde es eher mit einem doppelten Fork versuchen, wie Dämonen das machen:

1
( ( nohup sleep 300 ) & ) &

Das scheint bei mir zu funktionieren. Wenn ich das Terminal schließe, bleibt der sleep da und hat kein tty mehr, wie man mit ps sieht.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13224

rklm schrieb:

Ich würde es eher mit einem doppelten Fork versuchen, wie Dämonen das machen:

1
( ( nohup sleep 300 ) & ) &

Da ist ein Satz klammern überflüssig. So geht es auch:

1
2
( nohup sleep 300 & ) &
{ nohup sleep 300 & } &

Hm, aber das Controlling Terminal wird man damit nicht los:

$ ( nohup sleep 300 & ) & sleep 1; jobs -l; !ps
( nohup sleep 300 & ) & sleep 1; jobs -l; ps -o pid,ppid,pgid,tpgid,tty,cmd
[1] 4637
nohup: appending output to ‘nohup.out’
[1]+  Done                    ( nohup sleep 300 & )
  PID  PPID  PGID TPGID TT       CMD
 4414  4022  4414  4641 pts/3    bash
 4639  1674  4637  4641 pts/3    sleep 300
 4641  4414  4641  4641 pts/3    ps -o pid,ppid,pgid,tpgid,tty,cmd 

Allerdings kann ich auch Ctrl-C drücken, so viel ich will, der sleep wird nicht beendet.

Bei meinen Recherchen bin ich auf disown gestoßen, das etwas ähnliches macht wie der doppelte Fork.

Links zum Weiterlesen:

Mit dem Wissen aus dem letzten Artikel von Stackoverflow:

$ nohup setsid sleep 300 &
[1] 5021
$ nohup: ignoring input and appending output to ‘nohup.out’

[1]+  Done                    nohup setsid sleep 300
$ ps -o pid,ppid,pgid,tpgid,tty,cmd $(pgrep sleep)
  PID  PPID  PGID TPGID TT       CMD
 5022  1674  5022    -1 ?        sleep 300 

Man sieht, der sleep hat kein Controlling Terminal mehr. nohup sorgt dafür, dass die Ausgaben nicht mehr ins Terminal wandern. Man kann das aber auch so machen:

1
2
setsid sleep 300 <&- >&- 2>&- &
setsid sleep 300 <&- >/dev/null 2>&1 &

Anstatt "sleep 300" dann natürlich das andere Kommando.

Probier es mal aus, mit setsid sollte der Ctrl-C den Prozess jedenfalls nicht mehr beenden.

Antworten |