Ich habe eine Bash-Datei, die ich alle Ausgaben in eine Datei, Debug-Protokoll sowie auf das Terminal umleiten muss. Ich muss sowohl stdout als auch stderr zum Debug umleiten und es für alle Befehle im Skript protokollieren.
Ich möchte nicht 2>&1 | tee -a $DEBUG
für jeden einzelnen Befehl in der Datei hinzufügen . Ich könnte damit leben | tee -a $DEBUG
.
Ich erinnere mich, dass es einen Weg gab, dies mit so etwas wie zu tun exec 2>&1
.
Momentan 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?
bash
io-redirection
Avi
quelle
quelle
|&
die als Abkürzung für funktionieren2>&1 |
, ist es zumindest etwas praktischer.Antworten:
Eine Lösung, um viele Befehle auf einmal umzuleiten:
Warum Ihre ursprüngliche Lösung nicht funktioniert: exec 2> & 1 leitet die Standardfehlerausgabe an die Standardausgabe Ihrer Shell weiter, die, wenn Sie Ihr Skript von der Konsole aus ausführen, Ihre Konsole ist. Die Pipe-Umleitung bei Befehlen leitet nur die Standardausgabe des Befehls um.
Unter dem Gesichtspunkt von
somecommand
wird die Standardausgabe in eine Pipe geschrieben, die mit verbunden ist,tee
und der Standardfehler wird in dieselbe Datei / Pseudodatei geschrieben wie der Standardfehler der Shell, die Sie zur Standardausgabe der Shell umleiten Konsole, wenn Sie Ihr Programm von der Konsole aus ausführen.Der einzig wahre Weg, dies zu erklären, ist zu sehen, was wirklich passiert:
Die ursprüngliche Umgebung Ihrer Shell könnte folgendermaßen aussehen, wenn Sie sie vom Terminal aus ausführen:
Nachdem Sie den Standardfehler in die Standardausgabe (
exec 2>&1
) umgeleitet haben , ... ändern Sie im Grunde nichts. Wenn Sie jedoch die Standardausgabe des Skripts in eine Datei umleiten, erhalten Sie eine Umgebung wie die folgende:Das Umleiten des Shell-Standardfehlers in die Standardausgabe würde dann folgendermaßen enden:
Das Ausführen eines Befehls erbt diese Umgebung. Wenn Sie einen Befehl ausführen und ihn an tee weiterleiten, sieht die Umgebung des Befehls folgendermaßen aus:
Der Standardfehler Ihres Befehls geht also immer noch in das ein, was die Shell als Standardfehler verwendet.
Sie können die Umgebung eines Befehls tatsächlich anzeigen, indem Sie nachsehen
/proc/[pid]/fd
: Verwenden Siels -l
diese Option, um auch den Inhalt des symbolischen Links aufzulisten. Die0
Datei hier ist Standardeingabe,1
Standardausgabe und2
Standardfehler. Wenn der Befehl mehr Dateien öffnet (und die meisten Programme dies tun), werden sie auch angezeigt. Ein Programm kann auch wählen , um ihre Standard - Ein- / Ausgabe und Wiederverwendung zu umleiten oder zu schließen0
,1
und2
.quelle
Sie können exec wie folgt am oberen Rand Ihres Skripts verwenden:
Zum Beispiel:
Gibt mir eine Ausgabe in die Datei
$HOME/somefile.log
und in das Terminal wie folgt aus:quelle
/bin/sh
Skripten nicht universell funktioniert (viele Leute verwenden fälschlicherweise die Bash-Syntax in/bin/sh
Skripten)./dev/fd/62: Operation not supported
keine Hinweise?myscript
und ich laufe./myscript > /dev/null
, sollte ich immer noch sehen,bye
was kommtecho bye >&2
.Schreibe stderr und stdout in eine Datei, zeige stderr auf dem Bildschirm an (auf stdout)
Nützlich für Benutzer, damit Sie Fehler (und nur Fehler) per E-Mail erhalten können
quelle