Wie kann ich alle Bash-Skript-Aktionen vollständig protokollieren?

44

Ich möchte ALLE Protokolldaten mit Fehlermeldungen aus meiner Skriptausgabe erfassen und sie alle in die Protokolldatei umleiten.

Ich habe 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 einer Datei sehen /home/scripts/cron/logs

Aber ich sehe nur das, was ich nach dem Echobefehl setze.

Wie kann ich Protokolle einchecken, wenn der SSH-Befehl erfolgreich war?

Ich muss alle Protokolldaten erfassen. Ich brauche dies, um das Ergebnis jedes Befehls in meinem Skript zu überwachen und um besser analysieren zu können, was passiert, wenn ein Skript fehlschlägt.

BlueMark
quelle
Sie können dazu auch das "Skript" verwenden. Siehe diesen Beitrag: [hier] [1] [1]: stackoverflow.com/questions/5985060/…
xX0v0Xx
Sie müssen vorsichtig mit errexit sein - ich habe bemerkt, dass es ignoriert wird oder Fehler Skript nicht beendet, z. Wenn Sie so etwas im Skript haben: Befehl || dosmthg, wenn der Befehl fehlschlägt Das Skript wird nicht sofort mit aktiviertem Exit beendet, sondern es wird nur dosmthg ausgeführt und das Skript wird fortgesetzt

Antworten:

67

Im Allgemeinen schreibe ich zu Beginn eines jeden Skripts etwas Ähnliches wie das Folgende (insbesondere, wenn es als Daemon ausgeführt wird):

#!/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 oder zur Ausgabe auf die Dateien verwendet werden können, die vor der folgenden Umleitung vorhanden waren.

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

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

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

    Weiterleiten stdoutan Datei und log.outdann weiterleiten stderran stdout. Beachten Sie, dass die Reihenfolge wichtig ist, wenn Sie möchten, dass sie in dieselbe Datei verschoben werden. stdout muss umgeleitet werden, bevor zu umgeleitet stderrwird stdout.

Von da an können Sie einfach zu umleiten, um die Ausgabe auf der Konsole (möglicherweise) zu sehen &3. Zum Beispiel,

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

wird dorthin gehen, wohin stdoutes geleitet wurde, vermutlich zur Konsole, bevor Zeile 3 ausgeführt wurde.

nicerobot
quelle
<< niceroot, danke! Ich habe diese drei Zeilen (exec, trap, exec) am Anfang des Skripts hinzugefügt und kann sowohl stdout als auch stderr abrufen. Aber ein Problem: Ich habe gesehen, dass "Dateideskriptor 3 (Pipe: XXX) auf some_command" durchgesickert ist ... Bitte lassen Sie mich wissen, wie ich diese Fehler vermeiden kann. Ich benutze busybox-basierte sh in benutzerdefinierten Board.
Kumar
3
Tolles KungFu hier !!! - Noch besser ist zu bedienen trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Die RETURN-Pseudo-Sigspec-Wiederherstellungsdatei-Deskriptoren jedes Mal, wenn eine Shell-Funktion oder ein Skript mit der ausgeführt wird. oder source builtins beendet die Ausführung. Aus diesem Grund (und aus anderen Gründen) füge ich in meinen Skripten die letzten beiden Zeilen hinzu: return& exit 0- Nur meine 2 Cent, ein dickes Lob an Sie @nicerobot!
DavAlPi
Es gibt viele Details zur Protokollierung von Shell-Skripten über globale Variablen der Shell. Wir können die ähnliche Art der Protokollierung im Shell-Skript emulieren: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html Der Beitrag enthält Details zur Einführung von Protokollierungsstufen wie INFO, DEBUG, ERROR. Verfolgung von Details wie Skripteingang, Skripteingang, Funktionseingang, Funktionsexit.
Piyush Chordia
Die Aufzählung der trapSignale sieht etwas seltsam aus. Normalerweise möchten Sie auch einbeziehen 15.
Tripleee
1
@PiyushChordia Link behoben: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html
Wachsamkeit
14

den SSH - Ausgang mit Ihrem Logfile zu erhalten, müssen Sie umleiten stderrzu stdout. Sie können dies tun, indem Sie 2>&1nach Ihrem Bash-Skript anhängen .

es sollte so aussehen:

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

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

#!/bin/bash
((
...
) 2>&1) | tee ...
Christian
quelle
1
Das funktioniert super. Tatsächlich können Sie sowohl stdout als auch stderr leiten mit:( ... ) |& tee output.log
Noam Manos
13

Während 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 mit -x Shell-Skripte auf, um alles auszugeben:

sh -x foo.sh

Loggen Sie sich in die gewünschte Datei ein mit:

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

Alex Holst
quelle
2
+1 für -x Option
Coc
10

In bash können Sie put set -xund es wird jedes Kommando, das es ausführt (und die bash Variablen), danach ausgedruckt. Sie können es mit ausschalten set +x.

Wenn Sie paranoid sein möchten, können Sie set -o errexitIhr Skript einfügen. Dies bedeutet, dass das Skript fehlschlägt und stoppt, wenn ein Befehl einen Exit-Code ungleich Null zurückgibt. Dies ist der Unix-Standard, der signalisiert, dass ein Fehler aufgetreten ist.

Wenn Sie schönere Protokolle erhalten möchten, sollten Sie sich tsdas moreutilsdebian / ubuntu-Paket ansehen . Jeder Zeile wird ein Zeitstempel vorangestellt und ausgedruckt. So können Sie sehen, wann die Dinge geschahen.

Rory
quelle
1
"set -o errexit" muss dasselbe sein wie "set -e"
Ajith Antony
0

Nach dem, was andere gesagt haben, ist das Set- Handbuch eine gute Ressource. Ich legte:

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

Ganz oben in den Skripten möchte ich weitermachen oder set -exob es bei einem Fehler beendet wird.

dragon951
quelle
Wie kann dies für SSH-Protokolle und die erfolgreiche Ausführung von Befehlen hilfreich sein?
Asktyagi
Beim Testen mit dem Dummy-Skript des OP zeichnet es jeden Befehl und unabhängig vom Ergebnis auf: SSH-Zeitüberschreitung, falsche Domäne usw. Bei einer gültigen SSH-Adresse zeichnet es die Befehle in der Remote-Shell auf. Wenn Sie weitere Informationen zu SSH-Anmeldungen benötigen, vielleicht ssh -vv?
dragon951