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.
bash-script
null
JohnMerlino
quelle
quelle
/dev/null
verhindert nicht das Abstürzen, bereinigt jedoch die stdout- und stderr-Ausgabestreams.tar
kann auf verschiedene Weise Fehler verursachen. Sie haben möglicherweise keinen Schreibzugriff, die Datei ist möglicherweise bereits vorhanden usw.tar
es in der Quelle nicht vorhanden ist, weiltar
abgestürzt (man weiß es nie), weil auf dem Gerät kein Platz mehr vorhanden ist, weil dietar
Version 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.Antworten:
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>&1
alle Befehlsausgaben (sowohlstdout
als auchstderr
) an umgeleitet werden/dev/null
, werden keine Ausgaben an das Terminal ausgegeben .Standardmäßig:
Im Skript verwenden Sie die folgenden
> /dev/null
Ursachen:Und dann
2>&1
verursachen:quelle
> /dev/null 2>&1
führt dieser Befehl dazustderr ==> stdout
, dass stderr immer noch auf stdout ausgegeben wird.fd
?CMD > /dev/null 2>&1
arbeiten undCMD 2>&1 > /dev/null
trotzdem STDERR geben?2>& 1
in 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/file
steht. Die Umleitung in einen Dateideskriptor ist im Wesentlichen dasselbe.(Beachten Sie, dass ich die Umleitung zuvor
/dev/null
in Ihrer Frage hinzugefügt habe .)Das obige würde das
STDOUT
undSTDERR
zu umleiten/dev/null
. Es funktioniert durch Zusammenführen derSTDERR
in dieSTDOUT
. (Im Wesentlichen wird die gesamte Ausgabe des Befehls an das Nullgerät umgeleitet .)Es ist nicht ganz wie ein
try/catch
oder etwas. Es ist einfach zum Schweigen bringt , jede Art von Ausgang (einschließlich Fehler) aus dem Befehl.Dies kann aus verschiedenen Gründen zu Fehlern führen, darunter:
quelle
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.
quelle
Bash-E / A-Umleitung
Die Hauptidee, die Dinge zu klären, ist folgende:
Also dieser Code:
umleitet ,
stderr
umstdout
erste (2>&1
) , und dann sendetstdout
(einschließlich des umgeleitetenstderr
) bisfilename
(> filename
). Hier ist die ABSG-Erklärung (Kap. 20) .Dieser Code:
Umleitungen
stderr
undstdout
nach/dev/null
... was bedeutet, nirgendwo hin . Dinge, an die gesendet wird,/dev/null
werden 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."
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:
quelle
filename
und der Standardfehler an die Stelle weitergeleitet, an der die Standardausgabe gerade ausgegeben wirdfilename
. Wenn es umgekehrt wäre, würde der Standardfehler auf dem Terminal landen, während nur die Standardausgabe umgeleitet wurdefilename
. Auch incommand >file1 2>file2
,file2
würde nicht erstellt werden , wennfile1
nicht (egal ob erstellt werden kannfile1
undfile2
waren eigentlich ganz andere Pfadnamen).