Wie kann ich einen Prozess verzweigen, der beim Beenden der Shell nicht stirbt?

31

Wenn ich Emacs von der Shell aus starte:

$ emacs foo &

und dann töte diese Muschel, Emacs stirbt.

Wie kann ich einen Befehl ausführen, damit er nicht stirbt, wenn die Shell stirbt?

Ich habe Verweise auf nohup gefunden, aber das scheint nicht zu helfen:

$ nohup emacs foo &

tötet immer noch Emacs, wenn Shell stirbt.

sligocki
quelle

Antworten:

13

Sie erwähnen nicht, ob dies als X-App oder als Konsolen-App ausgeführt wird.

Wenn es sich um eine Konsolen-App handelt, muss sie natürlich geschlossen werden. Sie haben die Eingabe / Ausgabe entfernt, technisch gesehen die (Pseudo-) Ausgabe, auf der sie war. Es ist sehr unwahrscheinlich, dass Sie dies gemeint haben. Nehmen wir also an, Sie sprechen über eine X-App.

nohupsollte funktionieren, nicht sicher, warum es nicht ist. Wenn die Shell geschlossen wird, sendet sie SIGHUPan alle Prozesse in ihrer Prozessgruppe. nohup weist den Befehl an, SIGHUP zu ignorieren.

Sie können auch setsid ausprobieren, wodurch der Prozess von der Prozessgruppe getrennt wird

alias emacs='setsid emacs'

Oder fügen Sie disownnach&

Reiche Homolka
quelle
Ah, großartige Setsid-Werke. Tut mir leid, dass ich nicht klar bin. Ja, ich beziehe mich auf X-Apps, die nicht in der Shell ausgeführt werden. Grundsätzlich möchte ich Emacs (oder einen anderen Prozess) von der Shell aus starten, aber ich möchte nicht, dass es in irgendeiner Weise an die Shell gebunden ist. Ich beginne es nur der Einfachheit halber.
Sligocki
41

Die zuverlässigste Methode scheint zu sein:

(setsid emacs &)

Dies wird verwendet, ( &)um in den Hintergrund setsidzu wechseln und sich von der Steuerung zu lösen.

Sie können dies in eine Shell-Funktion einfügen:

fork() { (setsid "$@" &); }

fork emacs

Die Möglichkeiten sind:

  • Der disowneingebaute Befehl:

    emacs &
    disown $!
    

    &Dient als Befehlstrennzeichen und verwendet disownstandardmäßig den neuesten Job. Dies kann folgendermaßen verkürzt werden:

    emacs & disown
    
  • Doppel- fork():

    (emacs &)
    

    Befehle in Klammern ( )werden in einem separaten Shell-Prozess ausgeführt.

  • setsidWie von Rich vorgeschlagen, ist dies möglicherweise die beste Wahl, da hierdurch das steuernde TTY des Prozesses durch Erstellen einer neuen Sitzung deaktiviert wird :

    setsid emacs
    

    Es ist jedoch auch ein wenig unvorhersehbar - es tritt nur fork()im Hintergrund auf, wenn es der Leiter einer Prozessgruppe ist (was nicht der Fall setsidist , wenn es zum Beispiel in einem shSkript verwendet wird; in solchen Fällen wird es lediglich resistent gegen Strg- C.)

Grawity
quelle
Groß! diese arbeiten alle für mich. Schön, noch ein paar Werkzeuge in meinem Arsenal zu haben.
Sligocki
Hm ... würde (exec emacs)funktionieren?
Hallo71
@ Hallo: Es wäre nicht anders als nur (emacs). Wenn die Subshell einen einzelnen Befehl erhält, execwird der impliziert, zumindest im Fall von bash. Gleiches gilt für bash -c 'foo'versus bash -c 'exec foo'. (Beachten Sie jedoch, dass Emacs selbst vom Terminal abgenommen werden kann;.. Gvim zum Beispiel das tut Es ist besser, Test mit einem Programm mit bekannten Verhalten)
grawity
Toll, um die Doppelgabeltechnik zu erlernen; Vielen Dank!
Dave Abrahams
Fand dies beim Schleppen, um mein eigenes Problem zu beheben. Das (setsid & emacs) hat bei mir funktioniert. Vielen Dank für eine gut geschriebene Antwort.
Paulb
5

Überprüfen Sie die Shell-Einstellungen. Sie können auch versuchen, Bildschirm anstelle von nohup.

Josh K
quelle
Auf dem Bildschirm können Sie später wieder mit dem Vorgang beginnen, screen -rwenn Sie die Verbindung Ctrl-A Ctrl-Dtrennen, bevor Sie sich abmelden.
Broam
Das ist ein sehr guter Punkt. Ich brauchte das Gegenteil, nämlich eine Unterschale abzweigen und mit anderen Aufgaben fortzufahren, ohne auf die Fertigstellung zu warten, aber es screen -d -m sh -c "{do stuff } exit"ist viel sinnvoller.
Nemo