Beim Schreiben eines Linux-Shell-Skripts, um Programme sicher von einem Terminal zu trennen

9

Ich versuche ein Linux-Shell-Skript (vorzugsweise bash) zu schreiben, angeblich namens detach.sh , um Programme sicher von einem Terminal zu trennen, so dass:

  1. Aufruf: ./detach.sh prog [arg1 arg2 ...] .

  2. Ist exec -able, z. indem Sie dies in Ihrer Shell ausführen:

    %Vor%
  3. Mit richtiger Quotierung (hauptsächlich mit Argumenten, die Leerzeichen enthalten).

  4. Verwirft die Ausgaben (da sie nicht benötigt werden).

  5. Verwendet nicht screen , tmux usw. (Gleicher Grund mit 4, plus keine Notwendigkeit für einen zusätzlichen Babysitter-Prozess).

  6. Verwendet (einigermaßen) portable Befehle und Programme, und keine Dinge wie start-stop-daemon , die ziemlich streuspezifisch sind.

Ich habe mir verschiedene Wege ausgedacht (shebang linien #!/bin/bash vernachlässigt) aus Gründen der Kürze):

  1. nohup :

    %Vor%
  2. disown :

    %Vor%
  3. setsid :

    %Vor%
  4. Verwenden einer Untershell:

    %Vor%
  5. nohup / setsid kombiniert mit subshell:

    %Vor%

Wenn Sie gedit als Testprogramm verwenden (ersetzen Sie den "[email protected]" -Teil), Bedingung 1 kann mit allen oben genannten Methoden erfüllt werden, aber Bedingung 2 kann mit keiner zufrieden sein.

Wenn jedoch ein beliebiges Programm (aber keine eingebaute Shell) an Skript 5 angehängt wird, alle Bedingungen scheinen erfüllt zu sein (zumindest für mich im Fall gedit ). Zum Beispiel:

%Vor%

Jeder mit einer Idee über eine Erklärung der oben genannten Phänomene und wie man die Anforderungen richtig umsetzt?

BEARBEITEN:

Mit Bedingung 2, ich meine, das Programm sollte vom Terminal getrennt werden, läuft aber sonst wie gewohnt. Mit dem Fall gedit zum Beispiel schlägt die Bedingung fehl, wenn gedit unmittelbar nach Beendigung des Skriptprozesses beendet wird.

    
Casper Ti. Vector 20.04.2012, 13:57
quelle

3 Antworten

3

Bei näherer Untersuchung wurden diese bisher unbemerkten Fakten aufgedeckt:

  1. Beide Skripte 3 und 5 (nur die setsid Variante) erfülle alle Bedingungen, wenn ein /bin/true an das Skript angehängt ist.

  2. Diese Skripte, wie in der Tat 1 modifiziert, funktionieren auch, wenn /bin/true wird durch for i in {0..9999}; do :; done ersetzt.

Daraus können wir schließen, dass:

  • (Von Tatsache 1)

    Mehrere Ebenen der Ablösung (wie in Skript 5) sind nicht notwendig, und der Schlüssel ist, das richtige Dienstprogramm zu verwenden ( setsid ).

  • (Von Tatsache 2)

    Eine geeignete Verzögerung vor dem Bash-Exit ist für den Erfolg des Skripts notwendig. (Der Aufruf des externen Programms /bin/true benötigt etwas Zeit genau wie der pure-bash time consumer for i in {0..9999}; do :; done .)

    Ich habe mir den Quellcode nicht angesehen, aber ich schätze eine mögliche Erklärung Es ist möglich, dass bash beendet wird, bevor setsid die Ausführung der Konfiguration beendet Umgebung des Programms zu laufen, wenn eine entsprechende Verzögerung nicht angewendet wird.

Und schließlich sollte eine optimale Lösung

sein %Vor%

BEARBEITEN 1 :

Die Notwendigkeit einer Verzögerung wurde hier erläutert. Vielen Dank an @wilx!

BEARBEITEN 2 :

(Dank @MateiDavid) haben wir vergessen, die Standardeingabe umzuleiten, und ein besserer Weg wäre:

%Vor%     
Casper Ti. Vector 30.03.2014, 08:08
quelle
1

Ich denke, Sie müssen setsid "[email protected]" >& /dev/null & wait ausführen, damit das steuernde Terminal nicht verschwindet, bevor setsid das Kind unterteilen kann.

AKTUALISIEREN

Es scheint mir, dass dies sowohl in der Befehlszeile als auch als Argument von -c funktioniert:

%Vor%     
wilx 10.05.2016 09:46
quelle
0

Sie versuchen einen UNIX-Daemon-Prozess zu erstellen (dh einen Prozess, der kein kontrollierendes Terminal hat und das ist seine eigene Sitzung Führer). Der Befehl setsid sollte dies für Sie tun, aber Sie sind dafür verantwortlich, alle Dateideskriptoren zu schließen, die auf dem Terminal geöffnet sind, das Sie verlassen. Dies kann erfolgen, indem Sie sie an /dev/null umleiten oder die Shell-Syntax zum Schließen von Dateideskriptoren verwenden (z. B. 2>&- und 0<&- in Bash).

    
Francis Litterio 01.05.2012 19:15
quelle

Tags und Links