python 中的输出打印语句不会进入 cron 日志

python 中的输出打印语句不会进入 cron 日志

我的 crontab 看起来像这样:

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

内容shutdownlauncher.sh

cd /
cd home/pi/LCDinterface


date
python shutdown.py 
echo ''
cd /

内容shutdown.py

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

如果我运行python shutdown.py或者sh shutdownlauncher.sh我总是可以在终端中看到输出文本“关闭”。但是如果只有 cron 开始运行 bash 脚本,它会调用 python 脚本。我从未看到过该文本,它也没有出现在日志中。 sh 脚本中的命令date出现在我的日志中,但不在终端中。你能帮我吗?如何编辑shutdownlauncher.sh或 cron 作业以查看终端和日志中的输出?整个过程在 Raspberry Pi 3 上运行,我通过 SSH 连接。

我的日志文件的内容:

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

答案1

尝试使用 module 代替 print 函数syslog

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

答案2

比较:

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

和:

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

您会注意到,whenpython3的输出进入该管道,foo并且bar仅在末尾打印。

或者:

$ 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

与大多数语言一样,当标准输出不发送到终端设备(供用户使用)时,它会被缓冲,这样就不必进行太多不必要的写入。

由于shutdown最终会杀死包括该python脚本在内的每个进程,因此缓冲区永远不会被刷新。

您可以在调用之前明确请求刷新标准输出缓冲区shutdown(或kill在我的示例中):

$ 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

但在这里,该消息应该发送到 stderr 而不是 stdout,并且即使不发送到 tty 设备,stderr 也不会被缓冲,因此:

$ 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

相关内容