Ich habe ein Problem mit dem Nohup-Befehl.
Wenn ich meinen Job leite, 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?
Nohup schreibt nur in Nohup.out
, wenn die Ausgabe an das Terminal anders ist. Wenn Sie die Ausgabe des Befehls an eine andere Stelle umleiten - einschließlich /dev/null
-, wird dies stattdessen ausgeführt.
Nohup
verwenden, bedeutet dies wahrscheinlich, dass Sie den Befehl im Hintergrund ausführen möchten, indem Sie am Ende der gesamten Aktion ein anderesNohup command >/dev/null 2>&1 # doesn't create Nohup.out
setzen:Nohup
ausführen, wird die Eingabe automatisch geschlossen. Bei anderen Systemen, insbesondere bei BSD und macOS, ist dies nicht der Fall. Wenn Sie also im Hintergrund laufen, möchten Sie möglicherweise die Eingabe manuell schließen. Das Schließen von Eingaben hat keine Auswirkung auf die Erstellung von&
oder nicht, es vermeidet jedoch ein anderes 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:disown
ohne Argument als nächsten Befehl 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 automatisch von seiner übergeordneten Shell - aber ohneNohup
wird er immer noch beendet, wenn einHUP
-Signal empfangen wird, das über andere Mittel gesendet wird. B. einen manuellenkill
-Befehl. EinNohup
'ed-Prozess ignoriert alleHUP
-Signale, unabhängig davon, wie sie gesendet werden.)Erläuterung:
In Unixy-Systemen ist jeder Eingabe- oder Zielquelle eine Zahl 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, vor dem Start des Befehls zu ändern, wo einige oder alle diese Dateideskriptoren zeigen. das tun die Umleitungsoperatoren (
Nohup command >/dev/null 2>&1 & # runs in background, still doesn't create Nohup.out
,Nohup.out
,Nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal
,<
) und pipe (<<
).Die Pipe ist die einfachste davon ...
>
sorgt dafür, dass die Standardausgabe von>>
direkt in die Standardeingabe von|
eingespeist wird. 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 liest
command1 | command2
die Standardeingabe aus der Datei mit dem Nameninfile
, währendcommand1
den Standardfehler an das Ende der Datei mit dem Namenlogfile
anfügt. Wenn Sie keine Zahl angeben, ist die Eingabeumleitung standardmäßig auf fd 0 eingestellt (command2
ist mit0<infile
identisch), während die Umleitung der Ausgabe auf fd 1 eingestellt ist (2>>logfile
ist mit<
identisch).Sie können auch Dateideskriptoren zusammenfassen:
0<
bedeutet "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 Folge
>
bedeutet also "Standardausgabe an1>
senden" (was ein spezielles Gerät ist, das alles, was Sie darauf schreiben, wegwirft) "und dann Standardfehler an die Stelle senden, an die die Standardausgabe geht" (was gerade sichergestellt wurde, dass2>&1
war.) . Grundsätzlich "wegwerfen, was dieser Befehl in einen der Dateideskriptoren schreibt".Wenn
Nohup
feststellt, dass weder der Standardfehler noch die Ausgabe an ein Terminal angehängt ist, muss>/dev/null 2>&1
nicht erstellt werden. Es wird jedoch davon ausgegangen, dass die Ausgabe bereits an die gewünschte Stelle umgeleitet wurde.Das/dev/null
-Gerät funktioniert auch für die Eingabe. Wenn Sie einen Befehl mit/dev/null
ausführen, 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 lässt SieNohup.out
ausführen, was jedoch die Erstellung eines Prozesses mit einem in einem Ausgabestrom geöffneten Eingabedateideskriptor zur Folge hat. Wenn Sie also nicht nur das Dateiende aufrufen, wird jeder Leseversuch einen schwerwiegenden Fehler "ungültiger Dateideskriptor" auslösen .The
/dev/null
device works for input, too; if you run a command with</dev/null
, then any attempt by that command to read from standard input will instantly encounter end-of-file. Note that the merge syntax won't have the same effect here; it only works to point a file descriptor to another one that's open in the same direction (input or output). The Shell will let you do>/dev/null <&1
, but that winds up creating a process with an input file descriptor open on an output stream, so instead of just hitting end-of-file, any read attempt will trigger a fatal "invalid file descriptor" error.
Nohup some_command > /dev/null 2>&1&
Das ist alles was Sie tun müssen!
Haben Sie versucht, alle drei E/A-Streams umzuleiten:
Nohup ./yourprogram > foo.out 2> foo.err < /dev/null &
Möglicherweise möchten Sie das Detach-Programm verwenden. Sie verwenden es wie Nohup
, aber es erzeugt kein Ausgabeprotokoll, wenn Sie es nicht angeben. 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 Zugehörigkeit zum Autor des Programms. Ich bin nur ein zufriedener Benutzer des Programms.
Sudo bash -c "Nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null" &
Das Umleiten der Ausgabe von Sudo bewirkt, dass Sudo das Kennwort erneut sucht. Daher ist ein umständlicher Mechanismus für diese Variante erforderlich.
sie können dies unten tun Nohup &> 2> & 1 & z. B Ich habe keinen hup-Befehl im Skript ./Runjob.sh> sparkConcuurent.out 2> & 1
Wenn Sie eine BASH-Shell auf Ihrem Mac/Linux vor Ihnen haben, probieren Sie die folgenden Schritte aus, um die Umleitung praktisch zu verstehen:
Erstellen Sie ein zweizeiliges Skript namens zz.sh
#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
Beim einfachen Ausführen des Skripts werden derzeit sowohl STDOUT als auch STDERR an den Bildschirm gesendet.
./zz.sh
Beginnen Sie nun mit der Standardumleitung:
zz.sh > zfile.txt
Im obigen Beispiel wird "echo" (STDOUT) in die Datei "zfile.txt" eingefügt. Während auf dem Bildschirm "error" (STDERR) angezeigt wird.
Das obige ist das Gleiche wie:
zz.sh 1> zfile.txt
Jetzt können Sie das Gegenteil ausprobieren und "error" STDERR in die Datei umleiten. Der STDOUT-Befehl "Echo" wird auf dem Bildschirm angezeigt.
zz.sh 2> zfile.txt
Kombiniert man die beiden obigen Punkte, erhält man:
zz.sh 1> zfile.txt 2>&1
Erläuterung:
Irgendwann können Sie das Ganze in Nohup-Befehl & packen, um es im Hintergrund auszuführen:
Nohup zz.sh 1> zfile.txt 2>&1&