A instrução de impressão de saída em python não entra no cron log

A instrução de impressão de saída em python não entra no cron log

meu crontab está assim:

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

Conteúdo de shutdownlauncher.sh:

cd /
cd home/pi/LCDinterface


date
python shutdown.py 
echo ''
cd /

Conteúdo de shutdown.py:

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

Se eu executar python shutdown.pyou sh shutdownlauncher.shsempre puder ver o texto de saída 'desligando' no meu terminal. Mas se apenas o cron começar a executar o script bash, que chama o script python. Nunca vejo o texto e ele não aparece no log. O datecomando no script sh aparece no meu log, mas não no terminal. Você pode me ajudar com isso? Como editar o shutdownlauncher.shcron job para ver as saídas no terminal e no log também? Tudo isso roda em um Raspberry Pi 3, estou conectado em SSH.

Conteúdo do meu arquivo de log:

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

Responder1

Em vez da função de impressão, tente usar module syslog.

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

Responder2

Comparar:

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

Com:

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

Você notará que python3a saída de when vai para esse canal fooe barsó é impressa no final.

Ou:

$ 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 na maioria das linguagens, quando a saída padrão não vai para um dispositivo terminal (para consumo do usuário), ela é armazenada em buffer, o que evita a necessidade de fazer muitas gravações desnecessárias.

E como shutdownacaba matando todos os processos, incluindo esse pythonscript, o buffer nunca é liberado.

Você pode solicitar explicitamente que o buffer stdout seja liberado antes de chamar shutdown(ou killno meu exemplo):

$ 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

Mas aqui, essa mensagem deveria ir para stderr do que stdout e stderr não é armazenado em buffer mesmo que não vá para um dispositivo tty, então:

$ 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

informação relacionada