Frage Wie kann ich alle Aktionen der Bash-Skripte vollständig protokollieren?


Ich möchte alle Protokolldaten, beide mit Fehlermeldungen, aus meiner Skript-Ausgabe erfassen und sie alle in die Protokolldatei umleiten.

Ich habe ein Skript wie folgt:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs

Ich möchte alle Aktionen in der Datei sehen /home/scripts/cron/logs

Aber ich sehe nur das was ich nach echo befehle.

Wie man Protokolle eincheckt ist SSH Befehl war erfolgreich?

Ich muss alle Protokolldaten sammeln. Ich brauche dies, um das Ergebnis jedes Befehls in meinem Skript zu überwachen, um besser zu analysieren, was passiert, während das Skript fehlschlägt.


35
2018-01-17 11:17


Ursprung


Sie können auch das "Skript" verwenden, um dies durchzuführen. Siehe diesen Beitrag: [hier] [1] [1]: stackoverflow.com/questions/5985060/... - xX0v0Xx
Sie müssen vorsichtig sein mit errexit - ich habe festgestellt, dass es ignoriert wird oder Fehler Skript nicht beendet zB. Wenn Sie so etwas im Skript haben: command || dosmthg wenn Befehl fehlschlägt Skript wird nicht sofort mit errexit beendet, sondern nur dosmthg ausgeführt und das Skript fortgesetzt


Antworten:


Ich schreibe zu Beginn jedes Skripts etwas ähnliches wie das folgende (besonders wenn es als Daemon läuft):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

Erläuterung:

  1. exec 3>&1 4>&2

    Speichert Dateideskriptoren, damit sie vor der Umleitung wiederhergestellt werden können oder selbst für die Ausgabe vor der folgenden Weiterleitung verwendet werden.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    Stellen Sie Dateideskriptoren für bestimmte Signale wieder her. Im Allgemeinen nicht notwendig, da sie beim Verlassen der Sub-Shell wiederhergestellt werden sollten.

  3. exec 1>log.out 2>&1

    Umleiten stdout einordnen log.out dann umleiten stderr zu stdout. Beachten Sie, dass die Reihenfolge wichtig ist, wenn Sie möchten, dass sie in dieselbe Datei gehen. stdout  Muss vorher umgeleitet werden stderr wird umgeleitet zu stdout.

Ab dann, um die Ausgabe auf der Konsole zu sehen (vielleicht), können Sie einfach umleiten &3. Zum Beispiel,

echo "$(date) : part 1 - start" >&3

wird wohin gehen stdout wurde geleitet, vermutlich die Konsole, bevor Zeile 3 oben ausgeführt wurde.


52
2018-01-17 17:54



<< niceroot, Danke! Ich habe diese Threelines (exec, trap, exec) am Anfang des Skripts hinzugefügt und kann sowohl stdout als auch stderr bekommen. Aber ein Problem: Ich habe gesehen, dass "File descriptor 3 (pipe: XXX) auf irgendeinen Befehl geleakt wurde" ... Bitte lassen Sie mich wissen, wie ich vermeiden kann, diese Fehler zu bekommen. Ich benutze busybox basierte sh in benutzerdefinierten Board. - kumar
Tolles KungFu hier !!! - Noch besser ist zu verwenden trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Der RETURN-Pseudo-sigspec stellt die Dateideskriptoren jedes Mal wieder her, wenn eine Shell-Funktion oder ein Skript mit dem Skript ausgeführt wird. oder Source-Builtins beendet die Ausführung. Dafür (und aus anderen Gründen) in meinen Skripten füge ich als die letzten 2 Zeilen hinzu: return & exit 0 - Nur meine 2 Cent, ein großes Lob an Sie @nicerobot! - DavAlPi
Es gibt eine Menge Details über die Protokollierung von Shell-Skripten über globale Shell-Variablen. Wir können die ähnliche Art der Protokollierung im Shell-Skript emulieren: kubiarace.com/2016/03/efficient-logging-technism-in-shell.html  Der Beitrag enthält Details zu Protokollstufen wie INFO, DEBUG, ERROR. Ablaufverfolgung Details wie Skripteintrag, Skript-Exit, Funktionseingabe, Funktionsexit. - Piyush Chordia
Die Aufzählung von trap Signale sehen etwas komisch aus. In der Regel möchten Sie dies berücksichtigen 15 auch. - tripleee
@PiyushChordia Link reparieren: kubiarace.com/2016/03/efficient-logging-technism-in-shell.html - vigilancer


Um die ssh-Ausgabe in Ihre Logdatei zu bekommen, müssen Sie umleiten stderr zu stdout. Sie können dies durch Anhängen tun 2>&1 nach deinem Bash-Skript.

es sollte so aussehen:

#!/bin/bash
(
...
) 2>&1 | tee ...

Wenn die Meldungen nicht in der richtigen Reihenfolge angezeigt werden, versuchen Sie, eine weitere Untershell hinzuzufügen:

#!/bin/bash
((
...
) 2>&1) | tee ...

12
2018-01-17 12:24





Wenn ich Ihre Frage lese, möchten Sie nicht die Ausgabe protokollieren, sondern die gesamte Befehlsfolge. In diesem Fall helfen Ihnen die anderen Antworten nicht.

Rufen Sie Shell-Skripte mit -x auf, um alles auszugeben:

sh -x foo.sh

Melden Sie sich mit folgender Datei bei der gewünschten Datei an:

sh -x foo.sh >> /home/scripts/cron/logs


11
2018-01-17 18:02



+1 für die Option -x - Coc


In bash können Sie setzen set -x und es wird jeden Befehl, den es ausführt (und die Bash-Variablen) danach ausdrucken. Sie können es mit deaktivieren set +x.

Wenn Sie paranoid sein wollen, können Sie setzen set -o errexit in deinem Skript. Dies bedeutet, dass das Skript fehlschlägt und stoppt, wenn ein Befehl einen Nicht-Null-Beendigungscode zurückgibt. Dies ist die Unix-Standardmethode, um zu signalisieren, dass etwas schief gelaufen ist.

Wenn Sie schönere Protokolle bekommen wollen, sollten Sie sich das ansehen ts in dem moreutils debian / ubuntu Paket. Es wird jeder Zeile einen Zeitstempel vorangestellt und ausgedruckt. So können Sie sehen, wenn Dinge passieren.


10
2018-01-25 11:38



"set -o errexit" muss dasselbe sein wie "set -e" - Ajith Antony