Weiterleitung nach / dev / null

144

Ich lese ein Beispiel für ein Bash-Shell-Skript:

#!/bin/bash

# This script makes a backup of my home directory.

cd /home

# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1

# First remove the old bzip2 file.  Redirect errors because this generates some if the archive
# does not exist.  Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar

# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1

# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log

Ich versuche, die Verwendung von "/ dev / null 2> & 1" hier zu verstehen. Zuerst dachte ich, dass dieses Skript / dev / null verwendet, um Fehler ordnungsgemäß zu ignorieren, ohne das Skript zum Absturz zu bringen (ähnlich wie bei der Behandlung von Ausnahmen in Programmiersprachen). Weil ich nicht sehe, wie die Verwendung von tar zum Komprimieren eines Verzeichnisses in eine tar-Datei möglicherweise Fehler verursachen kann.

JohnMerlino
quelle
3
Das Umleiten auf /dev/nullverhindert nicht das Abstürzen, bereinigt jedoch die stdout- und stderr-Ausgabestreams. tarkann auf verschiedene Weise Fehler verursachen. Sie haben möglicherweise keinen Schreibzugriff, die Datei ist möglicherweise bereits vorhanden usw.
Sparhawk
3
Nur ein Trick, um unnötige Ausgaben zu vermeiden. Warum tar Fehler verursachen kann: weil das Zielverzeichnis nicht vorhanden ist, weil die Quelle nicht vorhanden ist, weil Sie keinen Schreibzugriff auf das Ziel haben, oder weil tares in der Quelle nicht vorhanden ist, weil tarabgestürzt (man weiß es nie), weil auf dem Gerät kein Platz mehr vorhanden ist, weil die tarVersion geändert wurde und jetzt eine andere Syntax erforderlich ist, weil der Datenträger einen E / A-Fehler verursacht hat. Ich bin sicher, Sie könnten mehr finden.
Terdon

Antworten:

223

Nein, das verhindert nicht, dass das Skript abstürzt. Wenn dabei Fehler auftreten tar(z. B .: Berechtigung verweigert, keine solche Datei oder kein solches Verzeichnis, ...), stürzt das Skript trotzdem ab.

Da bei Verwendung von > /dev/null 2>&1alle Befehlsausgaben (sowohl stdoutals auch stderr) an umgeleitet werden /dev/null, werden keine Ausgaben an das Terminal ausgegeben .

Standardmäßig:

stdin  ==> fd 0
stdout ==> fd 1
stderr ==> fd 2

Im Skript verwenden Sie die folgenden > /dev/nullUrsachen:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> fd 2

Und dann 2>&1verursachen:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> stdout
cuonglm
quelle
3
Nach dem Verständnis > /dev/null 2>&1führt dieser Befehl dazu stderr ==> stdout, dass stderr immer noch auf stdout ausgegeben wird.
Weishi Zeng
11
wahrscheinlich nicht zu wichtig, aber was ist fd?
Kev
7
Warum funktioniert: CMD > /dev/null 2>&1arbeiten und CMD 2>&1 > /dev/nulltrotzdem STDERR geben?
Dbmikus
3
Empfohlen: Verwenden Sie 2>& 1in Codebeispielen, um hervorzuheben, dass die Zahl und das kaufmännische Und Teil des Umleitungsoperators sind. Es ist üblich, dass bei der Umleitung in eine Datei ein Leerzeichen zwischen >und /path/to/filesteht. Die Umleitung in einen Dateideskriptor ist im Wesentlichen dasselbe.
Henk Langeveld
21

Ich versuche, die Verwendung von "> / dev / null 2> & 1" hier zu verstehen.

(Beachten Sie, dass ich die Umleitung zuvor /dev/nullin Ihrer Frage hinzugefügt habe .)

Das obige würde das STDOUTund STDERRzu umleiten /dev/null. Es funktioniert durch Zusammenführen der STDERRin die STDOUT. (Im Wesentlichen wird die gesamte Ausgabe des Befehls an das Nullgerät umgeleitet .)

... ohne das Skript zum Absturz zu bringen (ähnlich wie bei der Behandlung von Ausnahmen in Programmiersprachen).

Es ist nicht ganz wie ein try/catchoder etwas. Es ist einfach zum Schweigen bringt , jede Art von Ausgang (einschließlich Fehler) aus dem Befehl.

Weil ich nicht sehe, wie die Verwendung von tar zum Komprimieren eines Verzeichnisses in eine tar-Datei möglicherweise Fehler verursachen kann.

Dies kann aus verschiedenen Gründen zu Fehlern führen, darunter:

  • Unzureichende Berechtigungen für die Datei (en), die Sie archivieren möchten, oder für die Datei, in die Sie schreiben möchten
  • Mangel an Speicherplatz, um das Archiv zu erstellen
devnull
quelle
gut erklärt.
Aditya Gupta
7

Wenn Sie CMD> / dev / null 2> & 1 ausführen

STDOUT leitet nach / dev / null weiter, und dann leitet STDERR zu THE ADDRESS von STDOUT weiter, das auf / dev / null festgelegt wurde. Folglich zeigen sowohl STDOUT als auch STDERR nach / dev / null

Im Gegensatz dazu, wenn Sie CMD 2> & 1> / dev / null ausführen

STDERR leitet auf die Adresse von STDOUT weiter (in diesem Moment Dateideskriptor 1 oder / proc / self / fd / 1), und dann leitet STDOUT auf / dev / null weiter, STDERR leitet jedoch weiter auf fd1 weiter !! Infolgedessen wird die normale Ausgabe von STDOUT verworfen, aber die von STDERR kommenden Fehler werden weiterhin auf die Konsole geschrieben.

tyrannisieren
quelle
-2

Bash-E / A-Umleitung

Die Hauptidee, die Dinge zu klären, ist folgende:

Die Weiterleitungen werden von RECHTS nach LINKS angewendet, entgegen der Art und Weise, wie englische Sprecher normalerweise lesen.


Also dieser Code:

command > filename 2>&1

umleitet , stderrum stdout erste ( 2>&1) , und dann sendet stdout(einschließlich des umgeleiteten stderr) bis filename( > filename). Hier ist die ABSG-Erklärung (Kap. 20) .

Dieser Code:

command >>/dev/null 2>&1

Umleitungen stderrund stdoutnach /dev/null... was bedeutet, nirgendwo hin . Dinge, an die gesendet wird, /dev/nullwerden in keiner Weise gespeichert, zwischengespeichert oder gespeichert.

Sie werden einfach ins Nirgendwo geschickt und vergessen. Auf diese Weise können Sie Programme ausführen und sicherstellen, dass sie KEINE Ausgabe erzeugen und niemals in der Befehlszeile oder in einer Protokolldatei angezeigt werden.


Ich sehe diese Art von Frage ziemlich oft ... hauptsächlich, weil ich sie selbst nachschlagen musste, da ich seit Jahren nicht mehr programmiert habe. Hier einige nützliche Informationen aus dem ABSG:

"Umleitung bedeutet einfach, die Ausgabe einer Datei, eines Befehls, eines Programms oder eines Skripts zu erfassen und als Eingabe an eine andere Datei, einen anderen Befehl, ein anderes Programm oder ein anderes Skript zu senden."

2>&1 
# Redirects stderr to stdout.

command >>filename 2>&1
# Appends both stdout and stderr
#+  to the file "filename" ...

ABSG: Advanced Bash Scripting Guide: Der obige Link in Kapitel 20 ist ein Link zur E / A-Umleitungsseite des Open Source- Dokuments tldp.org mit dem Namen Advanced Bash Scripting Guide von Mendel Cooper. Es wird als "Eine eingehende Erforschung der Kunst des Shell-Skripts" aufgeführt und ich stimme absolut zu. Es ist eine großartige Ressource und hat jede Menge Antworten auf alle möglichen verrückten Situationen.

Weitere wertvolle Ressourcen: Im aktuellen / verwalteten Abschnitt (in verschiedenen praktischen Formaten wie HTML, PDF, Text usw.) auf der Seite mit den Projektleitfäden zur Linux-Dokumentation sind viele wertvolle Ressourcen enthalten . Hier sind einige, die ich für nützlich befunden habe:

Skeptycal
quelle
1
Nein, Weiterleitungen werden von links nach rechts behandelt. In Ihrem Beispiel wird die Standardausgabe an filenameund der Standardfehler an die Stelle weitergeleitet, an der die Standardausgabe gerade ausgegeben wird filename. Wenn es umgekehrt wäre, würde der Standardfehler auf dem Terminal landen, während nur die Standardausgabe umgeleitet wurde filename. Auch in command >file1 2>file2, file2würde nicht erstellt werden , wenn file1nicht (egal ob erstellt werden kann file1und file2waren eigentlich ganz andere Pfadnamen).
Kusalananda