
meine Crontab sieht so aus:
@reboot sh /home/pi/LCDinterface/shutdownlauncher.sh 2>&1 | tee -a /home/cronlog
Inhalt von shutdownlauncher.sh
:
cd /
cd home/pi/LCDinterface
date
python shutdown.py
echo ''
cd /
Inhalt von shutdown.py
:
if interrupt_happens:
print ("shutting down")
time.sleep(3)
os.system("sudo shutdown -h now")
python shutdown.py
Wenn ich oder ausführe sh shutdownlauncher.sh
, kann ich in meinem Terminal immer den Ausgabetext „shutting down“ sehen. Aber wenn nur Cron das Bash-Skript ausführt, das das Python-Skript aufruft, sehe ich den Text nie und er erscheint nicht im Protokoll. Der date
Befehl im SH-Skript erscheint in meinem Protokoll, aber nicht im Terminal. Können Sie mir dabei helfen? Wie bearbeite ich den shutdownlauncher.sh
oder den Cron-Job, um die Ausgaben im Terminal und auch im Protokoll anzuzeigen? Das Ganze läuft auf einem Raspberry Pi 3, ich bin über SSH verbunden.
Inhalt meiner Logdatei:
Fri Apr 7 19:26:33 CEST 2017
Fri Apr 7 19:36:11 CEST 2017
Fri Apr 7 21:18:45 CEST 2017
Sat Apr 8 00:08:09 CEST 2017
Sat Apr 8 00:29:31 CEST 2017
Sat Apr 8 10:08:17 CEST 2017
Sat Apr 8 11:58:35 CEST 2017
Antwort1
Versuchen Sie, anstelle der Druckfunktion das Modul zu verwenden syslog
.
import syslog
syslog.syslog('System is going to shutdown')
Antwort2
Vergleichen:
python3 -c 'import time; print("foo"); time.sleep(1); print("bar")'
Mit:
python3 -c 'import time; print("foo"); time.sleep(1); print("bar")' | cat
Sie werden feststellen, dass python3
die Ausgabe von an diese Pipe geht foo
und bar
nur am Ende gedruckt wird.
Oder:
$ python3 -c 'import os, signal; print("foo"); os.kill(os.getpid(), signal.SIGTERM); print("bar")'
foo
zsh: terminated python3 -c
$ python3 -c 'import os, signal; print("foo"); os.kill(os.getpid(), signal.SIGTERM); print("bar")' | cat
zsh: terminated python3 -c |
zsh: done cat
Wie in den meisten Sprachen wird die Standardausgabe, wenn sie nicht an ein Terminalgerät (für den Benutzergebrauch) gesendet wird, gepuffert. Dadurch werden viele unnötige Schreibvorgänge vermieden.
Und da dadurch shutdown
letztendlich alle Prozesse, einschließlich dieses python
Skripts, beendet werden, wird der Puffer nie geleert.
Sie können explizit anfordern, dass der Standardausgabepuffer vor dem Aufruf geleert wird shutdown
(oder kill
in meinem Beispiel):
$ python3 -c 'import os, signal, sys; print("foo"); sys.stdout.flush(); os.kill(os.getpid(), signal.SIGTERM); print("bar")' | cat
foo
zsh: terminated python3 -c |
zsh: done cat
Aber hier sollte diese Nachricht eher an stderr als an stdout gehen und stderr wird nicht gepuffert, selbst wenn es nicht an ein TTY-Gerät geht, also:
$ python3 -c 'import os, signal, sys; print("foo", file=sys.stderr); os.kill(os.getpid(), signal.SIGTERM); print("bar")' 2>&1 | cat
foo
zsh: terminated python3 -c 2>&1 |
zsh: done cat