La declaración de impresión de salida en Python no entra en el registro cron

La declaración de impresión de salida en Python no entra en el registro cron

mi crontab se ve así:

@reboot sh /home/pi/LCDinterface/shutdownlauncher.sh 2>&1 | tee -a /home/cronlog

Contenido de shutdownlauncher.sh:

cd /
cd home/pi/LCDinterface


date
python shutdown.py 
echo ''
cd /

Contenido de shutdown.py:

if interrupt_happens:
  print ("shutting down")
  time.sleep(3)
  os.system("sudo shutdown -h now")

Si ejecuto python shutdown.pyo sh shutdownlauncher.shsiempre puedo ver el texto de salida 'apagándose' en mi terminal. Pero si solo cron comienza a ejecutar el script bash, que llama al script python. Nunca veo el texto y no aparece en el registro. El datecomando en el script sh aparece en mi registro, pero no en la terminal. ¿Me puede ayudar con eso? ¿Cómo editar el shutdownlauncher.shtrabajo cron o el para ver las salidas en la terminal y también en el registro? Todo esto se ejecuta en una Raspberry Pi 3, estoy conectado por SSH.

Contenido de mi archivo de registro:

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

Respuesta1

En lugar de la función de impresión, intente utilizar el módulo syslog.

import syslog
syslog.syslog('System is going to shutdown')

Respuesta2

Comparar:

python3 -c 'import time; print("foo"); time.sleep(1); print("bar")'

Con:

python3 -c 'import time; print("foo"); time.sleep(1); print("bar")' | cat

Notarás que cuando python3la salida va a esa tubería fooy barsolo se imprime al final.

O:

$ 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

Como en la mayoría de los lenguajes, cuando la salida estándar no va a un dispositivo terminal (para consumo del usuario), se almacena en un buffer, lo que evita tener que realizar demasiadas escrituras innecesarias.

Y dado que shutdowntermina matando todos los procesos, incluido ese pythonscript, el búfer nunca se vacía.

Puede solicitar explícitamente que el búfer de salida estándar se vacíe antes de llamar shutdown(o killen mi ejemplo):

$ 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

Pero aquí, ese mensaje debería ir a stderr en lugar de a stdout y stderr no se almacena en el buffer incluso si no va a un dispositivo tty, entonces:

$ 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

información relacionada