bash: setze -x logs auf file

18

Ich habe ein Shell-Skript mit set -xausführlicher / Debug-Ausgabe:

#!/bin/bash

set -x
command1
command2
...

Die Ausgabe sieht folgendermaßen aus:

+ command1
whatever output from command1
+ command2
whatever output from command2

Mein Problem ist, der Shell - Ausgang (durch set -x) geht zum Stderr, mit der Ausgabe der Befehle vermischen ( command1, command2, ...). Ich würde mich freuen, wenn die "normale" Ausgabe auf dem Bildschirm (wie das Skript ohne ausgeführt würde set -x) und die "zusätzliche" Ausgabe von bash separat in einer Datei wären .

Deshalb möchte ich Folgendes auf dem Bildschirm haben:

whatever output from command1
whatever output from command2

und dies in einer Protokolldatei:

+ command1
+ command2

(Auch in Ordnung, wenn die Protokolldatei alles zusammen hat)

Die set -x 2> fileoffensichtlich nehmen doens't die richtige Wirkung, weil es nicht die Ausgabe des Befehls set, aber es das Verhalten der bash ändern.

Das Verwenden bash 2> filefür das gesamte Skript ist auch nicht richtig, da es den stderr jedes Befehls umleitet, der auch in dieser Shell ausgeführt wird, sodass die Fehlermeldung der Befehle nicht angezeigt wird.

Redseven
quelle
2
Mein google-fu scheint heute morgen stark zu sein: Sende die Ausgabe von bash -x in die Logdatei, ohne die Standardausgabe zu
unterbrechen

Antworten:

20

Auf der Grundlage dieser ServerFault Antwort Senden bash -x Ausgabe Logfile ohne Standardausgabe interupting , sind moderne Versionen von bash ein BASH_XTRACEFDspeziell für die Angabe eines alternativen Dateideskriptor für die Ausgabeset -x

So können Sie zum Beispiel tun

#!/bin/bash

exec 19>logfile
BASH_XTRACEFD=19

set -x
command1
command2
...

Senden der Ausgabe set -xin eine Datei logfileunter Beibehaltung der regulären Standardausgabe und der Standardfehlerströme für die folgenden Befehle.

Beachten Sie, dass die Verwendung von fd 19 willkürlich ist - es muss nur ein verfügbarer Deskriptor sein (dh nicht 0, 1, 2 oder eine andere Nummer, die Sie bereits zugewiesen haben).

Stahlfahrer
quelle
Das Bash-Trace-Protokoll wird zwar separat gespeichert, die beiden Ausgaben (stdout + stderr auf dem Bildschirm und der Bash-Trace in den Protokolldateien) sind jedoch nur schwer zu lesen, da sie nicht mehr synchron sind. Sehen Sie die Lösung, was ich gerade gepostet habe .
Redseven
4

Nach mehr als einem Jahr habe ich die richtige Lösung gefunden, um sowohl die "normale" Ausgabe (stdout + stderr - bash trace) als auch alle zusammen (stdout + stderr + bash trace) in einer Datei (bash.log) anzuzeigen. :

exec   > >(tee -ia bash.log)
exec  2> >(tee -ia bash.log >& 2)
exec 19> bash.log

export BASH_XTRACEFD="19"
set -x

command1
command2
Redseven
quelle
Das ist nur die Kombination aus der Antwort von steeldriver und dieser .
jarno
3

Steeldriver gab Ihnen einen Ansatz. Alternativ können Sie STDERR einfach in eine Datei umleiten:

script.sh 2> logfile

Dies bedeutet jedoch, dass sowohl die von der set -xOption erstellte Ausgabe als auch alle anderen Fehlermeldungen in die Datei geschrieben werden. Die Lösung von Steeldriver leitet nur die set -xAusgabe um, die wahrscheinlich Ihren Wünschen entspricht .

terdon
quelle
"... sowohl die Ausgabe, die mit der Option set -x erzeugt wurde, als auch alle anderen Fehlermeldungen gehen in die Datei." Und deshalb funktioniert es bei mir nicht. Mein Hauptproblem ist, dass ich "echte Fehler" nicht so leicht sehe, weil all diese Bash-Ausgaben an die stderr gehen. Das Umleiten der Kommandofehlermeldungen würde mir auch die "echten Fehler" auf eine andere Art und Weise verbergen.
Redseven
@redseven Ich fürchte, was Sie fragen, ist dann nicht sehr klar. Könnten Sie Ihre Frage bearbeiten und klären? Vermeiden Sie die Verwendung des Begriffs "Ausgabe" für alles, was nicht stdout ist. Möchten Sie i) die normale Ausgabe trennen? ii) durch Ihren Befehl ausgelöste Fehler und iii) setze -x? Ist die Antwort von Stahlfahrer dann nicht genug? Wenn nicht, zeigen Sie uns ein einfaches Skript, das wir kopieren können, und teilen Sie uns mit, wie es sich verhalten soll.
Terdon
@steeldriver hat die Frage bereits perfekt beantwortet.
Redseven
@redseven ah, dann cool. Da Ihr Kommentar so viel später kam, dachte ich, dass Sie noch etwas brauchen und ich konnte nicht sehen, wie die Antwort von steeldriver Ihr Problem nicht lösen konnte. Gut, dass dann alles sortiert ist.
Terdon