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.pysh 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

相關內容