Hintergrundjobs in Shell-Skripten

472
Glyph

Ich habe ein Shell-Skript script.shmit einem cmdim Hintergrund gestarteten Befehl, das heißt:

#!/bin/bash … cmd & … 

Wenn ich einen Terminal-Emulator öffne (ich habe xfce4-terminal und gnome-terminal ausprobiert) und darin laufe script.sh, wird mein Befehl cmdeffektiv ausgeführt und wie erwartet im Hintergrund ausgeführt.

Aber wenn ich einen Terminal-Emulator aus dem vorherigen (oder zu Beginn meiner Desktopsitzung, was mein eigentlicher Anwendungsfall ist) öffne und mein Skript mit ausführen

xfce4-terminal -H -x script.sh (or gnome-terminal -x script.sh) 

Der Befehl cmdwird nicht mehr ausgeführt.

Ich habe festgestellt, dass ich die Ausführung durch das Einfügen set -mmeines Skripts erzwingen kann, aber ich verstehe nicht, warum es in diesem Fall notwendig (noch ausreichend) ist und nicht im vorherigen. Wenn ich ein set -oSkript in mein Skript stecke, erhalte ich in beiden Fällen dieselbe Ausgabe.

Kann mir jemand dies erklären und / oder mir den richtigen Weg erklären, um mit Hintergrundjobs in Shell-Skripten fortzufahren? Vielen Dank!


BEARBEITEN: Eigentlich cmdwird in beiden Fällen ausgeführt, aber im zweiten Fall wird es sofort durch die Beendigung von beendet script.sh. Um dies zu verhindern, kann man verwenden nohup, aber es ist nicht genug, und es ist das Seltsamste für mich: Man muss auch sleep 1etwas oder ähnliches setzen, damit der Prozess ordnungsgemäß im Hintergrund gestartet und von der übergeordneten Shell getrennt wird. sonst wird es auch getötet.

Ich verstehe diesen Unterschied im Verhalten zwischen den beiden Shells wirklich nicht, da beide nicht interaktiv sind, wie in einem vorherigen Kommentar angegeben.

0
Wie stellen Sie sicher, dass "cmd" nicht ausgeführt wird? Ist es leicht und eindeutig in der Ausgabe von ps zu finden (und dauert es lange genug, um es zu finden), oder macht es einen Sound oder eine andere GUI-Anzeige? Xen2050 vor 6 Jahren 0
@ Xen2050 Normalerweise wähle ich für "cmd" etwas, das in einem Task-Manager angezeigt werden kann, wie "sleep n", wobei "n" groß genug ist. Aber man kann mit einer GUI etwas auswählen, wie zum Beispiel 'firefox' oder etwas anderes. Glyph vor 6 Jahren 0

2 Antworten auf die Frage

1
Tomasz Jakub Rup

Wenn Sie xfce4-trminaloder gnome-terminal(oder ein anderes Terminal) öffnen, befindet sich Ihre Shell im interaktiven Modus. Jedes Skript wird im interaktiven Modus ausgeführt.

Wenn Sie script.shdurchlaufen

xfce4-terminal -H -x script.sh 

oder

gnome-terminal -x script.sh 

oder ein anderes Terminal: Ihre Shell befindet sich im nicht interaktiven Modus.

Skripts können mit der -iOption oder mit einer #!/bin/bash -iKopfzeile zur Ausführung im interaktiven Modus gezwungen werden . Beachten Sie, dass dies zu unregelmäßigem Skriptverhalten oder Fehlernachrichten führen kann, auch wenn kein Fehler vorliegt.

Was ist set -m? Es ist Überwachungsmodus . Hintergrundprozesse laufen in einer separaten Prozessgruppe ab und eine Zeile mit ihrem Beendigungsstatus wird nach deren Abschluss gedruckt. Sie ist standardmäßig für interaktive Shells aktiviert.

Was ist set -o? Die aktuellen Einstellungen der Optionen werden in einem nicht festgelegten Format in die Standardausgabe geschrieben.

Warum set -ofunktioniert das?

Die Option -o wurde aus der KornShell übernommen, um die Anforderungen der Benutzer zu erfüllen. Zusätzlich zu seiner allgemein benutzerfreundlichen Benutzeroberfläche ist -o erforderlich, um den vi-Befehlszeilen-Bearbeitungsmodus bereitzustellen, für den die historische Praxis keinen Ein-Buchstaben-Optionsnamen liefert. (Obwohl es möglich gewesen wäre, einen solchen Brief zu erfinden, wurde erkannt, dass andere Bearbeitungsmodi entwickelt werden würden und -o genügend Namensraum für die Beschreibung solcher Erweiterungen bietet.)

Historische Implementierungen sind in dem Format, das für -o Optionsstatusberichte verwendet wird, inkonsistent. Das + o-Format ohne Optionsargument wurde hinzugefügt, um den tragbaren Zugriff auf die Optionen zu ermöglichen, die gespeichert und später beispielsweise mit einem Punktskript wiederhergestellt werden können.

Wie auch immer, set -mwird bevorzugt.

Nein… die Shell in Ihrem Terminal ist interaktiv, die zum Ausführen des Skripts aufgerufene Shell jedoch nicht. Das beobachte ich insbesondere, indem ich in meinem Skript "set -o" setze: In beiden Fällen ist die Ausgabe dieselbe, insbesondere was den Monitormodus betrifft, der auf "off" gesetzt ist (Standardeinstellung im nicht interaktiven Modus). Ich setze nicht "set -o", um zu sehen, ob es funktioniert, sondern um seine Ausgabe zu sehen. Glyph vor 6 Jahren 0
0
Glyph

Die Frage wurde auf Unix Stackexchange beantwortet (siehe auch zusätzliche Kommentare unter der Antwort). Es ist eine Frage, wer an wen das SIGHUP-Signal sendet und wann. Und eine Alternative zu set -m / set +mum cmd &in script.shist trap '' HUP / trap - HUP.