GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Stderr aller nachfolgenden Befehle mit Exec umleiten?

Ich habe eine Bash-Datei, die ich brauche, um die gesamte Ausgabe in eine Datei, das Debug-Protokoll sowie an das Terminal umzuleiten. Ich muss sowohl stdout als auch stderr zum Debug umleiten und es für alle Befehle im Skript protokollieren.

Ich möchte 2>&1 | tee -a $DEBUG für jeden einzelnen Befehl in der Datei. Ich könnte mit | tee -a $DEBUG .

Ich erinnere mich, dass es eine Möglichkeit gab, dies mit etwas wie exec 2>&1 zu tun .

Derzeit verwende ich etwas wie das Folgende:

#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG

aber es funktioniert nicht. Hat jemand eine Lösung/kann die Ursache erklären?

Akzeptierte Antwort:

Als Lösung, um viele Befehle auf einmal umzuleiten:

#!/bin/bash
{
    somecommand 
    somecommand2
    somecommand3
} 2>&1 | tee -a $DEBUGLOG

Warum Ihre ursprüngliche Lösung nicht funktioniert:exec 2>&1 leitet die Standardfehlerausgabe auf die Standardausgabe Ihrer Shell um, die, wenn Sie Ihr Skript von der Konsole aus ausführen, Ihre Konsole sein wird. Die Pipe-Umleitung bei Befehlen leitet nur die Standardausgabe des Befehls um.

Aus der Sicht von somecommand , seine Standardausgabe geht in eine Pipe, die mit tee verbunden ist und der Standardfehler geht in dieselbe Datei/Pseudodatei wie der Standardfehler der Shell, die Sie zur Standardausgabe der Shell umleiten, die die Konsole sein wird, wenn Sie Ihr Programm von der Konsole aus ausführen.

Der einzig wahre Weg, es zu erklären, ist zu sehen, was wirklich passiert:

Die ursprüngliche Umgebung Ihrer Shell könnte so aussehen, wenn Sie sie vom Terminal aus ausführen:

stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42

Nachdem Sie den Standardfehler in die Standardausgabe umgeleitet haben (exec 2>&1 ), du … änderst im Grunde nichts. Wenn Sie jedoch die Standardausgabe des Skripts in eine Datei umleiten, erhalten Sie am Ende eine Umgebung wie diese:

stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42

Dann würde das Umleiten des Shell-Standardfehlers in die Standardausgabe so enden:

stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file

Das Ausführen eines Befehls erbt diese Umgebung. Wenn Sie einen Befehl ausführen und ihn an tee weiterleiten, wäre die Umgebung des Befehls :

stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file

Der Standardfehler Ihres Befehls geht also immer noch in das, was die Shell als Standardfehler verwendet.

Verwandte:${!FOO} und zsh?

Sie können die Umgebung eines Befehls tatsächlich sehen, indem Sie in /proc/[pid]/fd nachsehen :Verwenden Sie ls -l um auch den Inhalt des symbolischen Links aufzulisten. Der Datei hier ist die Standardeingabe, 1 ist die Standardausgabe und 2 ist Standardfehler. Wenn der Befehl weitere Dateien öffnet (was bei den meisten Programmen der Fall ist), werden diese ebenfalls angezeigt. Ein Programm kann auch seine Standard-Eingabe/Ausgabe umleiten oder schließen und wiederverwenden , 1 und 2 .


Linux
  1. Linux – Hotkey in Linux Mint für „Alle Fenster anzeigen“?

  2. Wie kann ich mit .htaccess http auf https umleiten?

  3. Welcher Prozess verwendet alle meine Festplatten-E / A

  4. Standardeingabe dynamisch in einem Bash-Skript umleiten

  5. Leiten Sie die gesamte Ausgabe in eine Datei in Bash um

301-Umleitung mit NGINX

So leiten Sie stderr in Bash auf stdout um

STDERR / STDOUT eines Prozesses umleiten, NACHDEM er gestartet wurde, über die Befehlszeile?

Verwirrt über stdin, stdout und stderr?

Wie lösche ich alle Dateien in einem Ordner, aber lösche den Ordner nicht mit NIX-Standardbibliotheken?

Wie beende ich alle Prozesse eines Benutzers mit seiner UID?