%20zusammen%20mit%20der%20Fehlerausgabe%20(stderr).png)
Es gibt ein Skript, das über Cron mit der folgenden Zeile ausgeführt wird:
0 * * * * (/var/script.sh | tee -a /var/script.log)
Wie schreibe ich den Cron-Eintrag um, um sowohl die normale stdout
als auch die Fehlerausgabe zu erfassen stderr
? Sie müssen in unterschiedlichen Dateien abgelegt werden.
Antwort1
cron
Jobs werden standardmäßig ausgeführt sh
und unabhängig davon, ob es sh
sich um ein Bourne- oder POSIX- sh
kompatibles System handelt, lautet die Syntax:
0 * * * * /var/script.sh 2>&1 | tee -a /var/script.log
Dies führt |
dazu, dass die beiden Befehle auf beiden Seiten parallel ausgeführt werden, verbunden mit einer Pipe, wobei der Standardausgang (fd 1) des linken Befehls an das Schreibende der Pipe angeschlossen ist und der Standardeingang (fd 0) des rechten Befehls an das Lesende angeschlossen ist.
Durch Hinzufügen 2>&1
zum linken lassen wir fd 2 (stderr) auf die gleiche Ressource verweisen, wie sie von fd 1 angezeigt wird: das Schreibende der Pipe, sodass sowohl die normale als auch die Fehlerausgabe von script.sh
an die Pipe zu gehen tee
.
tee
schreibt es sowohl in seine Standardausgabe (die im Fall eines Cron-Jobs entweder eine Pipe oder eine temporäre Datei ist, die zum Senden einer E-Mail an den Benutzer verwendet wird) als auch in script.log
.
Diese Syntax funktioniert auch in der fish
Shell.
Mit (t)csh
oder (4.0 oder neuer) können Sie außerdem Folgendes tun zsh
:bash
SHELL=/bin/zsh # or tcsh, bash ...
0 * * * * /var/script.sh |& tee -a /var/script.log
(wo SHELL=/bin/zsh
erfahren Sie, wie Sie cron
zur Interpretation der Befehlszeilen eine andere Shell verwenden sollen).
In fish
würden Sie &|
anstelle von verwenden |&
.
Mit rc
(dem einstigen Nachfolger von sh
) oder Ableitungen lautet die Syntax:
SHELL=/bin/rc # or es, akanga
0 * * * * /var/script.sh >[2=1] | tee -a /var/script.log
Mit zsh
können Sie auch darauf verzichten, tee
dank seiner MULT_IOS
Funktion:
SHELL=/bin/zsh
0 * * * * /var/script.sh >&1 2>&2 >>& /var/script.log
Dies hätte außerdem den Vorteil, dass script.sh
der Beendigungsstatus von erhalten bliebe, und außerdem würde script.sh
stderr von zusätzlich zum ursprünglichen stderr gehen script.log
(obwohl das bei einem Cron-Job keinen großen Unterschied macht, wo stdout und stderr im Allgemeinen sowieso an die gleiche Stelle gehen).
Einige Bourne/POSIX-ähnliche Shells ( zumindest bash
, ksh93
, zsh
, yash
, ) verfügen über eine Option, die Sie verwenden können, um Fehler in jeder Komponente einer Pipeline melden zu können:mksh
pipefail
SHELL=/bin/ksh # or zsh, bash...
0 * * * * set -o pipefail && /var/script.sh 2>&1 | tee -a /var/script.log
Antwort2
cron möchte Sie über jeden Cron-Job informieren, der eine Ausgabe erzeugt. Es möchte Ihnen die Ergebnisse per E-Mail zusenden. Wenn Sie keine E-Mails von cron erhalten möchten, stellen Sie sicher, dass Ihre Jobs keine Ausgabe erzeugen: Verwenden Sie nicht tee
, sondern leiten Sie die Ausgabe einfach um.
0 * * * * /var/script.sh >> /var/script.log 2>&1
Beachten Sie auch, dass ich die Klammern entfernt habe: Es hat keinen Sinn, das Skript in einer Subshell auszuführen.