Standardfehler an Datei übergeben und Standardfehler beibehalten?

743
bgStack15

Ich habe ein Skript (Fragment), für das ich Ausgabe und Standardfehler protokolliere:

#!/bin/sh #... { date "+%Y-%m-%d %T" cd $workdir ls -ltr validfile badfile #example command that provides stdout, stderr } | tee -a $logfile 

Wenn ich das oben mache, bekomme ich Standard in der Logdatei. Um auch dort Standardfehler zu erhalten, könnte ich folgendes tun:

#!/bin/sh #... { date "+%Y-%m-%d %T" cd $workdir ls -ltr validfile badfile } 2>&1 | tee -a $logfile 

Aber diese Version in einem Skript, die von der Befehlszeile aus aufgerufen wird, erlaubt es mir nicht, Fehler zu analysieren:

$ ./script.sh 2>/dev/null 

Zeigt einfach alle Standardfehler und Standardfehler an. Was ist, wenn ich dieses Mal die Fehler einfach weiterentwickeln möchte?

Können Sie mir zeigen, wie Standardfehler an das Protokoll übergeben werden, aber den Standardfehler belassen, wenn er über die Befehlszeile oder ein anderes Skript aufgerufen wird?

AIX 7.1, ksh (keine Bash)

2

1 Antwort auf die Frage

3
bgStack15

Mit einer ausgefallenen Output-Umleitung können Sie dies auch ohne grundlegende Bash-Umleitung zu Prozessen erreichen.

Standardfehler protokollieren und in der Standardfehlerleitung speichern

#!/bin/sh exec 4>&1 # important as it "saves" stdout (usually /dev/tty2 for example) exec 3>&1 # work-in-progress file descriptor logfile=/var/log/myscript.out  { { date "+%Y-%m-%d %T" cd $workdir ls -ltr validfile badfile } 2>&1 1>&3 | tee -a $logfile 1>&2 2>/dev/null 3>&4 } 3>&1 | tee -a $logfile  exec 4>&- # proper form is to clean up when you're done exec 3>&- 

Erklärung:
exec 4>&1und exec 3>&1erstellen Sie neue Dateideskriptoren 3 und 4, die beide darauf verweisen, auf welchen Standard Sie hinweisen (auf Ihr Terminal höchstwahrscheinlich).

2>&1Leitet den Standardfehler der gesamten geschweiften Klammer der zweiten Ebene auf den Standardausgang um. 1>&3leitet den Standard auf das um, worauf fd3 hinweist (was Standard ist, aber nicht in Rohr 1, was von Bedeutung ist!)

| tee -a $logfilekopiert standard in (kommt von den geschweiften Klammern der zweiten Ebene, also der alte stderr) sowohl in die Logdatei als auch in den Standard out. 1>&2verschiebt Standard zu Standardfehler (also zurück, wo er hingehört) . 2>/dev/nullist wahrscheinlich nicht notwendig, leitet aber alle Fehlerausgaben von tee ab und wirft sie in den Papierkorb. 3>&4Leitet Rohr 3 zu Rohr 4 um (was übrigens auf stdout zeigt, nicht vergessen?).

3>&1Nimmt Rohr 3 der First-Level-Klammern ab und schickt es zur normalen Norm heraus . | tee -a $logfileerfasst die Standardeingabe (dh den [angepassten] Standard aus den geschweiften Klammern) und dupliziert sie mit dem Protokoll und dem Standardausgang.