Wie kann ich die Ausgabe eines Befehls unterdrücken, aber anzeigen, wenn der Befehlsexit einen Fehler codiert?
Leider ist die Annahme, stderr
die nur für die Fehlerausgabe verwendet wird, nicht immer richtig. Vielmehr wird stderr
es häufig für alle interaktiven Ausgaben und Diagnosen verwendet, dh für Ausgaben, die der Benutzer in einer interaktiven Eingabeaufforderung 1 einlesen soll . wget
und dd
sind bekannte Beispiele.
Einige Befehle enthalten ein Flag (z. B. -quiet
oder -silent
), um die fehlerfreie Ausgabe zu unterdrücken. Lesen Sie in den Manpages nach, ob eine vorhanden ist.
Eine andere Konvention, die häufiger angewendet wird, ist der Exit-Code : Ein Programm gibt beim Beenden einen Exit-Code zurück. In der Regel 2 zeigt ein Beendigungscode von 0
Erfolg an, und jeder andere Beendigungscode zeigt einen Fehler an.
Mit bash
können Sie den Exit-Code des letzten Befehls aus der $?
Variablen abrufen. In fish
, verwenden Sie die $status
Variable. Sie können eine Pipe stderr
zu einer temporären Datei erstellen und diese nur drucken, wenn ein Fehler auftritt. Zum Beispiel ( fish
):
command 2>/tmp/outputbuffer
if $status
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Sie können auch einige Verknüpfungen verwenden, wenn Sie keine Befehle verketten:
if command 2>/tmp/outputbuffer
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Oder:
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
Sie können mit auch eine Pipe stdout
zu demselben Puffer erstellen 2>&1 >/tmp/outputbuffer
.
(Hinweis: Ich weiß es nicht genau fish
, daher passe ich das Konzept an die Dokumentation an. Die Syntax ist möglicherweise etwas falsch. Sie können auch mktemp
eine eindeutige temporäre Datei erstellen. Führen Sie sie aus und zeichnen Sie die Datei auf Dateiname in einer Variablen.)
Wenn Sie das Ganze im Hintergrund einer Shell ausführen müssen, die Sie auch gleichzeitig interaktiv verwenden, sollten Sie ein Skript schreiben, um die Ausgabe zu verbergen und dieses Skript mit den Standardtechniken im Hintergrund auszuführen ( fish
). Heck, können Sie so etwas wie die folgende Funktion in setzen ~/.config/fish/config.fish
:
function run-silent
set temp (mktemp)
if $argv 2>&1 >$temp
cat $temp
rm $temp
end
Rufe mit auf run-silent somecommand &
(wo das Trailing dazu führt, &
dass es im Hintergrund läuft)
Beachten Sie, dass dies den ursprünglichen Beendigungscode verschluckt stdout
und stderr
im Falle eines Fehlers einen Speicherauszug erstellt. Sie können es nach Bedarf anpassen.
1 Es gibt nicht einmal die Garantie, dass die Fehlerausgabe nicht angezeigt wird stdout
- einige Programme geben die gesamte Ausgabe dort aus!
2 Leider ist dies immer noch nicht der Fall - der Exit-Code wird vollständig vom Programm gesteuert, und einige zeigen Erfolgsbedingungen mit Exits ungleich Null an. Überprüfen Sie erneut das Handbuch.
Unix-Dienstprogramme senden allgemeine Nachrichten an
stdout
und Fehlermeldungen anstderr
. Wenn wir also nur Fehlermeldungen anzeigen möchten, ist es ausreichend, diese zu unterdrücken,stdout
damit sie nurstderr
an die Konsole ausgegeben werden.Der Weg, dies zu tun (in beiden
bash
undfish
), besteht darin,>/dev/null
an den Befehl anzuhängen . Dies leitet stdout ins Nichts, aber stderr (mit Ihren Fehlermeldungen) kommt immer noch zur Konsole durch.Also zum Beispiel:
Der Befehl gibt
echo 1 >/dev/null
nichts aus, da die normalestdout
Ausgabe unterdrückt ist und nichts nach stderr geschrieben wurde.Der Befehl gibt
man doesnotexist >/dev/null
eine Fehlermeldung aus, daman
seine Fehlermeldung in geschrieben wirdstderr
.quelle
Dadurch wird der Befehl im Hintergrund ausgeführt und es werden Fehler in eine Protokolldatei geschrieben, wobei die normale Ausgabe ignoriert wird
quelle