Wie wird ein Linux-Befehl im Hintergrund ausgeführt?

18335
ShitalSavekar

Derzeit verwende ich es nohup command &, um es im Hintergrund zu senden. Aber das Problem ist: Wenn ich ausführen nohup command &, bekomme ich heraus wie folgt:

root@ubuntu:/home/test# nohup sleep 10 & [2] 52439 root@ubuntu:/home/test# nohup: ignoring input and appending output to `nohup.out' <I need to press ENTER key here to take back my shell control.> root@ubuntu:/home/test# 

Was ich tun muss :

root@ubuntu:/home/test# nohup sleep 10 & [2] 52439 root@ubuntu:/home/test# nohup: ignoring input and appending output to `nohup.out' root@ubuntu:/home/test# 

Ich möchte nicht danach "ENTER KEY" drücken nohup sleep 10 &.

Da ich gerade am Automatisierungsteil arbeite, muss ich nach dem Senden eines Befehls in den Hintergrund den nächsten Befehl ausführen, ohne eine Taste zu drücken. Mögen:

root@ubuntu:/home/test# nohup start-server.py & root@ubuntu:/home/test# nohup start-client.py & 

[ start-server.pymuss im Hintergrund laufen.] aber das Problem ist, dass nach dem Ausführen von start-server.py der nächste Befehl nicht ausgeführt wird. Ich muss "ENTER KEY" drücken, um zum nächsten Befehl zu gelangen.

Gibt es eine Lösung? Jede Hilfe wäre sehr dankbar.

2
Warum experimentieren Sie mit Befehlen als "root"? Verwenden Sie ein nicht privilegiertes Konto. chepner vor 11 Jahren 0
Write your nohup commands in one script say "script.sh" ... and execute it (sh script.sh) ... I hope it should work ... nd yes try a privileged account... Debaditya vor 11 Jahren 1
Sie brauchen nicht die EINGABETASTE zu drücken, nohup kann am Ende der Ausgabe einfach keine CR hinzufügen. Ihre Shell analysiert immer noch Ihre Eingabe. mathk vor 11 Jahren 0

4 Antworten auf die Frage

5
Uwe
nohup sleep 10 2>/dev/null & 

Der nohupBefehl gibt eine Nachricht an stderr aus und 2>/dev/nullsendet an stderr /dev/null.

Danke Uwe .. Du hast den Tag gerettet ..! Ihre Antworten waren genau das, wonach ich gesucht hatte. vor 11 Jahren 0
3
Jens

Keine Eingabe erforderlich. Geben Sie einfach Ihren nächsten Befehl ein und es wird funktionieren (was Sie sehen, ist nur eine Ausgabe, nachdem Ihre Shell-Eingabeaufforderung ausgegeben wurde). Dies ist genau das Gleiche wie beim Eingeben an der Shell-Eingabeaufforderung: Sie erhalten eine weitere Eingabeaufforderung. :-)

2
chepner

Sie müssen nicht wirklich die Eingabetaste drücken. Obwohl es so aussieht, als sei der Standardfehler von nohup in Ihrer Befehlszeile, können Sie ihn "überschreiben" und nur das, was Sie eingeben, wird als nächster Befehl eingegeben.

0
Kangarooo

Von https://stackoverflow.com/a/10408906/738947

nohup schreibt nur, nohup.outwenn die Ausgabe an das Terminal anders ist. Wenn Sie die Ausgabe des Befehls an eine andere Stelle umleiten - einschließlich /dev/null-, geht es stattdessen weiter.

 nohup command >/dev/null 2>&1 # doesn't create nohup.out 

Wenn Sie verwenden nohup, bedeutet dies wahrscheinlich, dass Sie den Befehl im Hintergrund ausführen möchten, indem Sie einen anderen &an das Ende des Ganzen setzen:

 nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out 

Wenn Sie unter Linux einen Job nohupausführen, wird auch dessen Eingabe automatisch geschlossen. Bei anderen Systemen, insbesondere bei BSD und OS X, ist dies nicht der Fall. Wenn Sie im Hintergrund laufen, möchten Sie möglicherweise die Eingabe manuell schließen. Das Schließen von Eingaben hat keine Auswirkungen auf die Erstellung oder nicht von nohup.out, verhindert jedoch ein weiteres Problem: Wenn ein Hintergrundprozess versucht, etwas aus der Standardeingabe zu lesen, wird er angehalten und wartet, bis Sie ihn wieder in den Vordergrund bringen und etwas eingeben. Die besonders sichere Version sieht also so aus:

nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal 

Beachten Sie jedoch, dass dies den Befehl weder daran hindert, direkt auf das Terminal zuzugreifen, noch ihn aus der Prozessgruppe Ihrer Shell entfernt. Wenn Sie das letztere tun möchten, können Sie dies ausführen, indem Sie disownals nächsten Befehl kein Argument ausführen. Zu diesem Zeitpunkt ist der Prozess nicht mehr mit einem Shell- "Job" verknüpft und es werden keine Signale (nicht nur HUP) an ihn weitergeleitet aus der Schale.

Erläuterung:

In Unixy-Systemen ist jeder Eingabe- oder Zielquelle der Ausgabe eine Nummer zugeordnet, die als "Dateideskriptor" oder kurz "fd" bezeichnet wird. Für jedes laufende Programm ("Prozess") gibt es eine eigene Gruppe, und wenn ein neuer Prozess gestartet wird, sind bereits drei davon geöffnet: "Standard input" (fd 0) ist offen, damit der Prozess lesen kann "Standardausgabe" (fd 1) und "Standardfehler" (fd 2) sind offen für das Schreiben. Wenn Sie nur einen Befehl in einem Terminalfenster ausführen, werden alle Eingaben standardmäßig in die Standardeingabe übernommen, während sowohl die Standardausgabe als auch der Standardfehler an dieses Fenster gesendet werden.

Sie können die Shell jedoch bitten, zu ändern, wo einige oder alle Dateideskriptoren zeigen, bevor Sie den Befehl starten. das ist, was die Umleitung ( <, <<, >, >>) und Rohr ( |) Betreiber tun.

Die Pipe ist die einfachste dieser ... command1 | command2ordnet die Standardausgabe von command1direkt in die Standardeingabe von ein command2. Dies ist eine sehr praktische Anordnung, die zu einem bestimmten Entwurfsmuster in UNIX-Werkzeugen geführt hat (und erklärt das Vorhandensein von Standardfehlern, wodurch ein Programm Nachrichten an den Benutzer senden kann, obwohl seine Ausgabe in das nächste Programm in der Pipeline geht). . Sie können die Standardausgabe jedoch nur an die Standardeingabe übergeben. Sie können keine anderen Dateideskriptoren ohne Jonglieren an eine Pipe senden.

Die Umleitungsoperatoren sind freundlicher, da Sie angeben können, welcher Dateideskriptor umgeleitet werden soll. So 0<infileliest die Standardeingabe von der Datei mit dem Namen infile, während 2>>logfileanhängt Standardfehler an das Ende der benannten Datei logfile. Wenn Sie keine Zahl angeben, wird die Eingangsumleitung standardmäßig auf fd 0 gesetzt ( <ist die gleiche wie 0<), während die Ausgangsumleitung auf fd 1 ( >gleich wie 1>) eingestellt ist.

Sie können auch Dateideskriptoren zusammenfassen: 2>&1bedeutet "Standardfehler senden, wohin die Standardausgabe geht". Das bedeutet, dass Sie einen einzigen Ausgabestrom erhalten, der sowohl Standardausgang als auch Standardfehler enthält, ohne dass eine Trennung mehr möglich ist. Dies bedeutet jedoch auch, dass Sie Standardfehler in eine Pipe aufnehmen können.

Die Sequenz >/dev/null 2>&1bedeutet also "Standardausgabe senden an /dev/null" (ein spezielles Gerät, das alles, was Sie darauf schreiben, einfach wegwirft) "und dann Standardfehler an die Standardausgabe senden" (was gerade sichergestellt wurde /dev/null). Grundsätzlich "wegwerfen, was dieser Befehl in einen der Dateideskriptoren schreibt".

Wenn nohupfeststellt, dass weder der Standardfehler noch die Ausgabe an ein Terminal angehängt ist, ist die Erstellung nicht erforderlich, es wird jedoch davon ausgegangen nohup.out, dass die Ausgabe bereits dorthin umgeleitet wurde, wo der Benutzer sie wünscht.

Das /dev/nullGerät funktioniert auch für die Eingabe. Wenn Sie einen Befehl mit ausführen </dev/null, wird jeder Versuch dieses Befehls, die Standardeingabe zu lesen, sofort auf das Dateiende stoßen. Beachten Sie, dass die Zusammenführungssyntax hier nicht denselben Effekt hat. Es funktioniert nur, um einen Dateideskriptor auf einen anderen zu zeigen, der in derselben Richtung geöffnet ist (Eingabe oder Ausgabe). Die Shell erlaubt es Ihnen, dies zu tun >/dev/null <&1, aber das Erstellen eines Prozesses mit einem Eingabedateideskriptor, der in einem Ausgabestrom geöffnet ist, führt dazu, dass der Leseversuch nicht nur das Dateiende trifft, sondern einen schwerwiegenden Fehler "ungültiger Dateideskriptor" auslöst.