Wie verwende ich den Befehl nohup, ohne nohup.out zu erhalten?
309
Ich habe ein Problem mit dem Befehl nohup.
Wenn ich meinen Job ausführe, habe ich viele Daten. Die Ausgabe nohup.out wird zu groß und mein Prozess verlangsamt sich. Wie kann ich diesen Befehl ausführen, ohne nohup.out zu erhalten?
Der nohupBefehl schreibt nur, nohup.outwenn die Ausgabe sonst an das Terminal gehen würde. Wenn Sie die Ausgabe des Befehls an eine andere Stelle umgeleitet haben - einschließlich /dev/null-, wird diese stattdessen ausgeführt.
Wenn Sie verwenden nohup, bedeutet dies wahrscheinlich, dass Sie den Befehl im Hintergrund ausführen möchten, indem Sie &am Ende des Ganzen einen weiteren Befehl einfügen:
nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out
Unter Linux schließt das Ausführen eines Jobs mit nohupautomatisch auch seine Eingabe. Auf anderen Systemen, insbesondere BSD und macOS, ist dies nicht der Fall. Wenn Sie also im Hintergrund ausgeführt werden, möchten Sie die Eingabe möglicherweise manuell schließen. Das Schließen der Eingabe hat zwar keine Auswirkung auf die Erstellung oder Nichterstellung von nohup.out, vermeidet jedoch ein anderes Problem: Wenn ein Hintergrundprozess versucht, etwas von der Standardeingabe zu lesen, wird er angehalten und wartet darauf, dass Sie es wieder in den Vordergrund stellen und etwas eingeben. Die besonders sichere Version sieht also so aus:
Beachten Sie jedoch, dass dies weder den direkten Zugriff des Befehls auf das Terminal verhindert noch ihn aus der Prozessgruppe Ihrer Shell entfernt. Wenn Sie Letzteres ausführen möchten und bash, ksh oder zsh ausführen, können Sie dies tun, indem Sie disownals nächsten Befehl ohne Argument ausführen. Dies bedeutet, dass der Hintergrundprozess nicht mehr mit einem Shell- "Job" verknüpft ist und keine Signale von der Shell an ihn weitergeleitet werden. (Beachten Sie die Unterscheidung: Ein disowned-Prozess erhält keine Signale, die von seiner übergeordneten Shell automatisch an ihn weitergeleitet werden. Ohne nohupdiese Funktion erhält er jedoch weiterhin ein HUPSignal, das auf andere Weise gesendet wird, z. B. durch einen manuellen killBefehl. Ein nohuped-Prozess ignoriert alle HUPSignale. egal wie sie gesendet werden.)
Erläuterung:
In Unixy-Systemen ist jeder Eingabequelle oder jedem Ausgabeziel eine Nummer zugeordnet, die als "Dateideskriptor" oder kurz "fd" bezeichnet wird. Jedes laufende Programm ("Prozess") hat einen eigenen Satz davon, und wenn ein neuer Prozess gestartet wird, sind drei davon bereits geöffnet: "Standardeingabe", fd 0, ist offen, damit der Prozess lesen kann, während "Standardausgabe" (fd 1) und "Standardfehler" (fd 2) können geöffnet werden. Wenn Sie nur einen Befehl in einem Terminalfenster ausführen, wird standardmäßig alles, was Sie eingeben, an die Standardeingabe gesendet, 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 dieser Dateideskriptoren zeigen, bevor Sie den Befehl starten. das ist , was die Umleitung ( <, <<, >, >>) und Rohr ( |) Betreiber tun.
Das Rohr ist das einfachste von diesen ... command1 | command2sorgt dafür, dass die Standardausgabe von command1direkt in die Standardeingabe von eingespeist wird command2. Dies ist eine sehr praktische Anordnung, die zu einem bestimmten Entwurfsmuster in UNIX-Tools geführt hat (und das Vorhandensein eines Standardfehlers erklärt, der es einem Programm ermöglicht, Nachrichten an den Benutzer zu senden, obwohl seine Ausgabe in das nächste Programm in der Pipeline geht). . Sie können jedoch nur die Standardausgabe an die Standardeingabe weiterleiten. Sie können keine anderen Dateideskriptoren an eine Pipe senden, ohne etwas zu jonglieren.
Die Umleitungsoperatoren sind insofern freundlicher, als 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, dann Eingabeumleitung standardmäßig auf fd 0 ( <ist die gleiche wie 0<), während die Umleitung der Ausgabe Standardwert 1 bis fd ( >ist das gleiche wie 1>).
Sie können auch Dateideskriptoren miteinander kombinieren: 2>&1bedeutet "Standardfehler senden, wohin auch immer die Standardausgabe geht". Dies bedeutet, dass Sie einen einzelnen Ausgabestream erhalten, der sowohl Standardausgang als auch Standardfehler enthält, ohne dass eine Trennung mehr möglich ist. Es 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 einfach alles wegwirft, was Sie darauf schreiben) "und dann Standardfehler an die Standardausgabe senden" (was wir gerade sichergestellt haben /dev/null). Grundsätzlich "wegwerfen, was auch immer dieser Befehl in einen der Dateideskriptoren schreibt".
Wenn nohupfestgestellt wird, dass weder der Standardfehler noch die Ausgabe an ein Terminal angehängt sind, wird keine Erstellung durchgeführt nohup.out, sondern es wird davon ausgegangen , dass die Ausgabe bereits dorthin umgeleitet wird, wo der Benutzer sie haben möchte.
Das /dev/nullGerät funktioniert auch für die Eingabe; Wenn Sie einen Befehl mit ausführen </dev/null, wird jeder Versuch dieses Befehls, aus der Standardeingabe zu lesen, sofort auf das Dateiende stoßen. Beachten Sie, dass die Zusammenführungssyntax hier nicht den gleichen Effekt hat. Es funktioniert nur, um einen Dateideskriptor auf einen anderen zu verweisen, der in derselben Richtung geöffnet ist (Eingabe oder Ausgabe). Die Shell lässt Sie dies tun >/dev/null <&1, aber das führt dazu , dass ein Prozess mit einem in einem Ausgabestream geöffneten Eingabedateideskriptor erstellt wird. Anstatt nur das Dateiende zu treffen, löst jeder Leseversuch einen schwerwiegenden "ungültigen Dateideskriptor" -Fehler aus.
In Bezug auf nohup"Wenn der Prozess später versucht, etwas von der Standardeingabe zu lesen, wird er angehalten und wartet darauf, dass Sie es wieder in den Vordergrund stellen und etwas eingeben." scheint falsch. nohupSchließt
Tim
1
@Tim - Diese Antwort ist für Linux korrekt, jedoch nicht für BSD oder OS X, bei denen nohupdie Standardeingabe nicht automatisch geschlossen wird. Beachten Sie, dassnohup keine integrierte Shell ist, sondern ein binäres Dienstprogramm.
Mark Reed
Nohup ist Teil von Coreutils. Meinen Sie, dass die Implementierung von nohupfür Linux und für BSD oder OS X unterschiedlich ist?
Tim
Ja. Der Name "coreutils" bezieht sich auf ein GNU-Paket. Aber BSD, OS X, SmartOS / Illumos und viele kommerzielle Unixe - im Grunde diejenigen, die es schon länger als GNU gibt - haben Nicht-GNU-Kerndienstprogramme. awkist anders,sed ist anders, nohupist anders ...
Sollte es nicht eher >/ dev / null als </ dev / null sein?
Scott Chu
3
@ScottChu < /dev/nullleitet die Standardeingabe für um nohup. Linux benötigt dies nicht, aber POSIX erlaubt ein Verhalten, bei dem nohupes nicht im Hintergrund ausgeführt werden kann, wenn die Standardeingabe mit dem Terminal verbunden ist. Beispiele für solche Systeme sind BSD und OS X.
Mikko Rantalainen
8
Möglicherweise möchten Sie das Programm zum Trennen verwenden . Sie verwenden es wie, nohupaber es wird kein Ausgabeprotokoll erstellt, es sei denn, Sie weisen es an. Hier ist die Manpage:
NAME
detach - run a command after detaching from the terminal
SYNOPSIS
detach [options] [--] command [args]
Forks a new process, detaches is from the terminal, and executes com‐
mand with the specified arguments.
OPTIONS
detach recognizes a couple of options, which are discussed below. The
special option -- is used to signal that the rest of the arguments are
the command and args to be passed to it.
-e file
Connect file to the standard error of the command.
-f Run in the foreground (do not fork).
-i file
Connect file to the standard input of the command.
-o file
Connect file to the standard output of the command.
-p file
Write the pid of the detached process to file.
EXAMPLE
detach xterm
Start an xterm that will not be closed when the current shell exits.
AUTHOR
detach was written by Robbert Haarman. See http://inglorion.net/ for
contact information.
Hinweis Ich habe keine Verbindung zum Autor des Programms. Ich bin nur ein zufriedener Benutzer des Programms.
Das Umleiten der Ausgabe von sudo führt dazu, dass sudo nach dem Kennwort sucht. Daher ist für diese Variante ein umständlicher Mechanismus erforderlich.
Antworten:
Der
nohup
Befehl schreibt nur,nohup.out
wenn die Ausgabe sonst an das Terminal gehen würde. Wenn Sie die Ausgabe des Befehls an eine andere Stelle umgeleitet haben - einschließlich/dev/null
-, wird diese stattdessen ausgeführt.Wenn Sie verwenden
nohup
, bedeutet dies wahrscheinlich, dass Sie den Befehl im Hintergrund ausführen möchten, indem Sie&
am Ende des Ganzen einen weiteren Befehl einfügen:Unter Linux schließt das Ausführen eines Jobs mit
nohup
automatisch auch seine Eingabe. Auf anderen Systemen, insbesondere BSD und macOS, ist dies nicht der Fall. Wenn Sie also im Hintergrund ausgeführt werden, möchten Sie die Eingabe möglicherweise manuell schließen. Das Schließen der Eingabe hat zwar keine Auswirkung auf die Erstellung oder Nichterstellung vonnohup.out
, vermeidet jedoch ein anderes Problem: Wenn ein Hintergrundprozess versucht, etwas von der Standardeingabe zu lesen, wird er angehalten und wartet darauf, dass Sie es wieder in den Vordergrund stellen und etwas eingeben. Die besonders sichere Version sieht also so aus:Beachten Sie jedoch, dass dies weder den direkten Zugriff des Befehls auf das Terminal verhindert noch ihn aus der Prozessgruppe Ihrer Shell entfernt. Wenn Sie Letzteres ausführen möchten und bash, ksh oder zsh ausführen, können Sie dies tun, indem Sie
disown
als nächsten Befehl ohne Argument ausführen. Dies bedeutet, dass der Hintergrundprozess nicht mehr mit einem Shell- "Job" verknüpft ist und keine Signale von der Shell an ihn weitergeleitet werden. (Beachten Sie die Unterscheidung: Eindisown
ed-Prozess erhält keine Signale, die von seiner übergeordneten Shell automatisch an ihn weitergeleitet werden. Ohnenohup
diese Funktion erhält er jedoch weiterhin einHUP
Signal, das auf andere Weise gesendet wird, z. B. durch einen manuellenkill
Befehl. Einnohup
ed-Prozess ignoriert alleHUP
Signale. egal wie sie gesendet werden.)Erläuterung:
In Unixy-Systemen ist jeder Eingabequelle oder jedem Ausgabeziel eine Nummer zugeordnet, die als "Dateideskriptor" oder kurz "fd" bezeichnet wird. Jedes laufende Programm ("Prozess") hat einen eigenen Satz davon, und wenn ein neuer Prozess gestartet wird, sind drei davon bereits geöffnet: "Standardeingabe", fd 0, ist offen, damit der Prozess lesen kann, während "Standardausgabe" (fd 1) und "Standardfehler" (fd 2) können geöffnet werden. Wenn Sie nur einen Befehl in einem Terminalfenster ausführen, wird standardmäßig alles, was Sie eingeben, an die Standardeingabe gesendet, 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 dieser Dateideskriptoren zeigen, bevor Sie den Befehl starten. das ist , was die Umleitung (
<
,<<
,>
,>>
) und Rohr (|
) Betreiber tun.Das Rohr ist das einfachste von diesen ...
command1 | command2
sorgt dafür, dass die Standardausgabe voncommand1
direkt in die Standardeingabe von eingespeist wirdcommand2
. Dies ist eine sehr praktische Anordnung, die zu einem bestimmten Entwurfsmuster in UNIX-Tools geführt hat (und das Vorhandensein eines Standardfehlers erklärt, der es einem Programm ermöglicht, Nachrichten an den Benutzer zu senden, obwohl seine Ausgabe in das nächste Programm in der Pipeline geht). . Sie können jedoch nur die Standardausgabe an die Standardeingabe weiterleiten. Sie können keine anderen Dateideskriptoren an eine Pipe senden, ohne etwas zu jonglieren.Die Umleitungsoperatoren sind insofern freundlicher, als Sie angeben können, welcher Dateideskriptor umgeleitet werden soll. So
0<infile
liest die Standardeingabe von der Datei mit dem Nameninfile
, während2>>logfile
anhängt Standardfehler an das Ende der benannten Dateilogfile
. Wenn Sie keine Zahl angeben, dann Eingabeumleitung standardmäßig auf fd 0 (<
ist die gleiche wie0<
), während die Umleitung der Ausgabe Standardwert 1 bis fd (>
ist das gleiche wie1>
).Sie können auch Dateideskriptoren miteinander kombinieren:
2>&1
bedeutet "Standardfehler senden, wohin auch immer die Standardausgabe geht". Dies bedeutet, dass Sie einen einzelnen Ausgabestream erhalten, der sowohl Standardausgang als auch Standardfehler enthält, ohne dass eine Trennung mehr möglich ist. Es bedeutet jedoch auch, dass Sie Standardfehler in eine Pipe aufnehmen können.Die Sequenz
>/dev/null 2>&1
bedeutet also "Standardausgabe senden an/dev/null
" (ein spezielles Gerät, das einfach alles wegwirft, was Sie darauf schreiben) "und dann Standardfehler an die Standardausgabe senden" (was wir gerade sichergestellt haben/dev/null
). Grundsätzlich "wegwerfen, was auch immer dieser Befehl in einen der Dateideskriptoren schreibt".Wenn
nohup
festgestellt wird, dass weder der Standardfehler noch die Ausgabe an ein Terminal angehängt sind, wird keine Erstellung durchgeführtnohup.out
, sondern es wird davon ausgegangen , dass die Ausgabe bereits dorthin umgeleitet wird, wo der Benutzer sie haben möchte.Das
/dev/null
Gerät funktioniert auch für die Eingabe; Wenn Sie einen Befehl mit ausführen</dev/null
, wird jeder Versuch dieses Befehls, aus der Standardeingabe zu lesen, sofort auf das Dateiende stoßen. Beachten Sie, dass die Zusammenführungssyntax hier nicht den gleichen Effekt hat. Es funktioniert nur, um einen Dateideskriptor auf einen anderen zu verweisen, der in derselben Richtung geöffnet ist (Eingabe oder Ausgabe). Die Shell lässt Sie dies tun>/dev/null <&1
, aber das führt dazu , dass ein Prozess mit einem in einem Ausgabestream geöffneten Eingabedateideskriptor erstellt wird. Anstatt nur das Dateiende zu treffen, löst jeder Leseversuch einen schwerwiegenden "ungültigen Dateideskriptor" -Fehler aus.quelle
nohup
"Wenn der Prozess später versucht, etwas von der Standardeingabe zu lesen, wird er angehalten und wartet darauf, dass Sie es wieder in den Vordergrund stellen und etwas eingeben." scheint falsch.nohup
Schließtnohup
die Standardeingabe nicht automatisch geschlossen wird. Beachten Sie, dassnohup
keine integrierte Shell ist, sondern ein binäres Dienstprogramm.nohup
für Linux und für BSD oder OS X unterschiedlich ist?awk
ist anders,sed
ist anders,nohup
ist anders ...</dev/null
? Siehe auch0>/dev/null
unix.stackexchange.com/a/266247Das ist alles was Sie tun müssen!
quelle
&
wird Sie davon abhalten, es zu benutzenctrl-c
, wenn es Ihnen wichtig ist.some_command
Ausgaben einschließlich Fehlern beschäftigen.Haben Sie versucht, alle drei E / A-Streams umzuleiten:
quelle
>
/ dev / null als </ dev / null sein?< /dev/null
leitet die Standardeingabe für umnohup
. Linux benötigt dies nicht, aber POSIX erlaubt ein Verhalten, bei demnohup
es nicht im Hintergrund ausgeführt werden kann, wenn die Standardeingabe mit dem Terminal verbunden ist. Beispiele für solche Systeme sind BSD und OS X.Möglicherweise möchten Sie das Programm zum Trennen verwenden . Sie verwenden es wie,
nohup
aber es wird kein Ausgabeprotokoll erstellt, es sei denn, Sie weisen es an. Hier ist die Manpage:Hinweis Ich habe keine Verbindung zum Autor des Programms. Ich bin nur ein zufriedener Benutzer des Programms.
quelle
Mit dem folgenden Befehl können Sie etwas im Hintergrund ausführen, ohne nohup.out zu erhalten:
Auf diese Weise können Sie die Konsolenausgabe erhalten, während Sie das Skript auf dem Remote-Server ausführen:
quelle
Das Umleiten der Ausgabe von sudo führt dazu, dass sudo nach dem Kennwort sucht. Daher ist für diese Variante ein umständlicher Mechanismus erforderlich.
quelle
Wenn Sie eine BASH-Shell auf Ihrem Mac / Linux vor sich haben, probieren Sie die folgenden Schritte aus, um die Umleitung praktisch zu verstehen:
Erstellen Sie ein zweizeiliges Skript mit dem Namen zz.sh.
Derzeit werden durch einfaches Ausführen des Skripts sowohl STDOUT als auch STDERR an den Bildschirm gesendet.
Beginnen Sie nun mit der Standardumleitung:
Oben geht "echo" (STDOUT) in die zfile.txt. Während "Fehler" (STDERR) auf dem Bildschirm angezeigt wird.
Das Obige ist dasselbe wie:
Jetzt können Sie das Gegenteil versuchen und "error" STDERR in die Datei umleiten. Der Befehl STDOUT from "echo" wechselt zum Bildschirm.
Wenn Sie die beiden oben genannten kombinieren, erhalten Sie:
Erläuterung:
Schließlich können Sie das Ganze in den Befehl nohup packen und im Hintergrund ausführen:
quelle
Sie können den folgenden Befehl ausführen.
zB habe ich einen nohup Befehl im Skript
quelle