So führen Sie einen Befehl im Hintergrund ohne Ausgabe aus, es sei denn, es liegt ein Fehler vor

14

Wie kann ich die Ausgabe eines Befehls unterdrücken, aber anzeigen, wenn der Befehlsexit einen Fehler codiert?

Xster
quelle

Antworten:

17

Leider ist die Annahme, stderrdie nur für die Fehlerausgabe verwendet wird, nicht immer richtig. Vielmehr wird stderres häufig für alle interaktiven Ausgaben und Diagnosen verwendet, dh für Ausgaben, die der Benutzer in einer interaktiven Eingabeaufforderung 1 einlesen soll . wgetund ddsind bekannte Beispiele.

Einige Befehle enthalten ein Flag (z. B. -quietoder -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 0Erfolg an, und jeder andere Beendigungscode zeigt einen Fehler an.

Mit bashkönnen Sie den Exit-Code des letzten Befehls aus der $?Variablen abrufen. In fish, verwenden Sie die $statusVariable. Sie können eine Pipe stderrzu 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 stdoutzu 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 mktempeine 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 stdoutund stderrim 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.

Bob
quelle
Es gibt einen speziellen Ort für das Einfügen von Funktionen in ~ / .config / fish / functions /
Xster
12

Unix-Dienstprogramme senden allgemeine Nachrichten an stdoutund Fehlermeldungen an stderr. Wenn wir also nur Fehlermeldungen anzeigen möchten, ist es ausreichend, diese zu unterdrücken, stdoutdamit sie nur stderran die Konsole ausgegeben werden.

Der Weg, dies zu tun (in beiden bashund fish), besteht darin, >/dev/nullan 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/nullnichts aus, da die normale stdoutAusgabe unterdrückt ist und nichts nach stderr geschrieben wurde.

Der Befehl gibt man doesnotexist >/dev/nulleine Fehlermeldung aus, da manseine Fehlermeldung in geschrieben wird stderr.

Maximillian Laumeister
quelle
2

Dadurch wird der Befehl im Hintergrund ausgeführt und es werden Fehler in eine Protokolldatei geschrieben, wobei die normale Ausgabe ignoriert wird

    command > /dev/null 2> /tmp/example_error.log &
Genkus
quelle