Wenn das Skript von einem Systemdämon ausgeführt wird und dieser Dämon mit Root-Rechten ausgeführt wird, müssen Sie es zunächst nicht verwenden sudo
. Dies beinhaltet init
(und systemd
), einschließlich rc.local
. Wenn dieser Daemon nicht mit Root-Rechten ausgeführt sudo
wird, funktioniert er nur, wenn er /etc/sudoers
so konfiguriert ist (und ohne Kennwort). Raspbian-Benutzer können dadurch verwirrt sein, da der pi
Benutzer standardmäßig alles tun darf (und wenn Sie hineinschauen, werden /etc/sudoers
Sie sehen, wie dies erreicht wird).
Als Nächstes können Sie die Ausgabe eines beliebigen bash
Skripts oder eines beliebigen Befehlssatzes in einem Bash-Skript erfassen , indem Sie sie in einer Subshell wie folgt ausführen: 1
(
/bin/foo on 3
sudo bar a
) &> /var/log/myTestLog.txt
Das ()
zeigt eine Unterschale an . Alle Ausgaben von irgendetwas in diesem werden in eine /var/log/myTestLog.txt
Datei umgeleitet . Ein paar Anmerkungen:
&>
ist ein Bashismus . Wenn das Skript also über einen Shebang in der ersten Zeile ausgeführt wird, sollte dies #!/bin/bash
nicht nur der Fall sein /bin/sh
. "Bashisms" funktionieren nur in der bash
Shell.
Dies schließt ein /etc/rc.local
, was standardmäßig verwendet wird /bin/sh
(dh ja, Sie können dies sicher in ändern /bin/bash
).
/var/log
erfordert Root-Rechte zum Schreiben. Wenn der Prozess nicht über ein solches verfügt, verwenden oder erstellen Sie ein Verzeichnis, von dem Sie wissen, dass es dies kann. Wenn Sie im Zweifelsfall dies testen können, ohne das System herunterfahren oder neu starten zu müssen, verwenden Sie /tmp
, was weltweit beschreibbar ist (dh von jedermann). Bleibt /tmp
jedoch nicht über Stiefel hinweg bestehen. Es ist auch eine kleine RAM-basierte Partition. Schreiben Sie also keine Datenmengen darauf. Es ist nicht Ihre SD-Karte [tatsächlich auf aktuellen Versionen von Raspbian, aber rechnen Sie in der Praxis nicht damit] .
&>
wird alles in überschreiben myTestLog.txt
. Wenn Sie stattdessen an ein vorhandenes Protokoll anhängen möchten, was für Debugging-Zwecke eine gute Idee sein könnte, verwenden Sie &>>
. Sie können dann am Anfang dieser Unterschale einen Befehl wie folgt hinzufügen:
echo Starting $(date)
Um die Informationen von jedem Lauf zu trennen. Wenn Sie sich nicht sicher sind, was dies bewirkt, versuchen Sie es in der Befehlszeile.
Dieser letzte Punkt ist ein gutes Beispiel dafür, was Sie in Bezug auf Befehle tun können, die nichts ausgeben - aber die meisten tun dies, wenn Sie z. B. -v
"ausführlich" einschließen . Vorsicht bei einigen Befehlen -v
bedeutet "Versionsinformationen drucken". Schauen Sie in der Manpage nach dem Befehl, um sicherzugehen, ob und wie dies funktioniert (einige Befehle verwenden auch einen anderen Schalter als -v
).
Konventionell geben Befehle nach Abschluss auch den Wert 0 zurück. Dies wird manchmal als "Exit-Status" bezeichnet und wird normalerweise nicht angezeigt, aber die Shell zeigt es Ihnen an echo $?
. Versuchen
ls /
echo $?
ls /nonexistantdir
echo $?
Sie erhalten 0 und 2. Wenn Sie dann in der Manpage ls
unter "Status beenden" nachsehen , sehen Sie das eher unspezifische, kryptische:
2 if serious trouble (e.g., cannot access command-line argument).
Was vielleicht besser ist oder nicht als nichts, aber los geht's.
Zumindest bedeutet dies, dass der Befehl aus irgendeinem Grund fehlgeschlagen ist. Mit dem Exit-Status können Sie auch Folgendes tun:
/bin/foo && sudo bar
Das bedeutet &&
in diesem Fall "wenn der erste Befehl erfolgreich ist", vorausgesetzt, der erste Befehl verwendet die Konvention der Rückgabe von 0 (weshalb dies normalerweise der Fall ist). Wenn /bin/foo
es nicht funktioniert, nicht gefunden werden kann usw., sudo bar
wird es niemals passieren.
Die Verwendung einer Kombination aus Protokollierungsnachrichten und bedingter Ausführung ( &&
) sollte Sie dem Herausfinden des Problems viel näher bringen oder zumindest Informationen abrufen, die für andere bei der Lösung des Problems hilfreich sein könnten. Ohne das kann niemand mehr raten.
1. Sie können dieselbe Ausgabeausleitung für ein gesamtes Skript von innen ausführen, indem Sie Folgendes verwenden:
exec &> /var/log/myTestLog.txt
Oben (oder irgendwo anders, und es gilt für alles, was danach folgt).
U&L
. Ich habe den Titel falsch verstanden und würde vorschlagen, dass "Protokollieren der Ausgabe eines Systemskripts zum Debuggen" den Zweck klarer macht. Auch mein Gehirn friert ein, wenn ich diesefoo
bar
Beispiele lese . Ich bevorzuge etwas, das realer aussieht. Ich zögere es, Beiträge zu bearbeiten. Ich überlasse dies Ihnen, wenn Sie der Meinung sind, dass sie verbessert werden können.