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?

Ofer
quelle

Antworten:

612

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.

 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 &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:

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

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.

Mark Reed
quelle
1
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. nohup Schließ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 ...
Mark Reed
Warum hast du "extra safe" von geschrieben </dev/null? Siehe auch 0>/dev/null unix.stackexchange.com/a/266247
Tim
68
nohup some_command > /dev/null 2>&1&

Das ist alles was Sie tun müssen!

11101101b
quelle
4
Es gab eine andere Antwort, die fast dasselbe hatte, aber sie hatten am Ende kein zusätzliches "&".
11101101b
10
Das &wird Sie davon abhalten, es zu benutzen ctrl-c, wenn es Ihnen wichtig ist.
SunSparc
1
Die Fähigkeit, in BG zu laufen, ist sehr hilfreich
ist_lion
Dies ist nur nützlich, wenn Sie sich nicht mit der Erfassung von some_commandAusgaben einschließlich Fehlern beschäftigen.
Wulfgarpro
12

Haben Sie versucht, alle drei E / A-Streams umzuleiten:

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &
Aziz Shaikh
quelle
1
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.

Dan D.
quelle
2
Die Verbindung ist nicht unterbrochen und das Git-Repo ist alt. Die aktuelle Version 0.2.3 ist nicht enthalten.
Dan D.
5

Mit dem folgenden Befehl können Sie etwas im Hintergrund ausführen, ohne nohup.out zu erhalten:

nohup command |tee &

Auf diese Weise können Sie die Konsolenausgabe erhalten, während Sie das Skript auf dem Remote-Server ausführen: Geben Sie hier die Bildbeschreibung ein

Clownfisch
quelle
4
sudo bash -c "nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null"  &

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.

Kjeld Flarup
quelle
1

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.

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • Die Ausgabe des Echo-Befehls geht in den STDOUT-Dateistream (Dateideskriptor 1).
  • Die Ausgabe des Fehlerbefehls geht in den STDERR-Dateistream (Dateideskriptor 2).

Derzeit werden durch einfaches Ausführen des Skripts sowohl STDOUT als auch STDERR an den Bildschirm gesendet.

./zz.sh

Beginnen Sie nun mit der Standardumleitung:

zz.sh > zfile.txt

Oben geht "echo" (STDOUT) in die zfile.txt. Während "Fehler" (STDERR) auf dem Bildschirm angezeigt wird.

Das Obige ist dasselbe wie:

zz.sh 1> zfile.txt

Jetzt können Sie das Gegenteil versuchen und "error" STDERR in die Datei umleiten. Der Befehl STDOUT from "echo" wechselt zum Bildschirm.

zz.sh 2> zfile.txt

Wenn Sie die beiden oben genannten kombinieren, erhalten Sie:

zz.sh 1> zfile.txt 2>&1

Erläuterung:

  • Senden Sie zunächst STDOUT 1 an zfile.txt
  • DANN senden Sie STDERR 2 an STDOUT 1 selbst (mit dem Zeiger & 1).
  • Daher gehen sowohl 1 als auch 2 in dieselbe Datei (zfile.txt).

Schließlich können Sie das Ganze in den Befehl nohup packen und im Hintergrund ausführen:

nohup zz.sh 1> zfile.txt 2>&1&
Thyag
quelle
1

Sie können den folgenden Befehl ausführen.

nohup <your command> & >  <outputfile> 2>&1 &

zB habe ich einen nohup Befehl im Skript

./Runjob.sh > sparkConcuurent.out 2>&1
Prem S.
quelle