下記の構成でPythonスクリプトを定期実行しています。
標準出力はcron_normal.logに、標準エラー出力はcron_error.logにしています。
test.py
import time print("test") time.sleep(100) print "test"
test.sh
python3.6 test.py
crontab -e
00 12 * * * test.sh 1>cron_normal.log 2>cron_error.log
状況
まず、Pythonスクリプトの処理が終了するまで、一切の出力がありません。また、途中でエラーが出ると、それまでに出力されるはずだった標準出力は無視され、標準エラー出力のみ書き込まれます
質問
Pythonスクリプトからの出力を、処理の終了を待たずに、順次ファイルに書き込むにはどうすればよいでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答4件
0
ベストアンサー
cronジョブでは試していないのですが、flush
を併用してみたらいかがでしょうか。標準入出力のflush
はpython3ではバージョンによって使い方に差異があるようですので、
Python3
1# 3.3以降なら 2print("test", flush=True) 3 4# 3.3より前なら 5import sys 6print("test"); 7sys.stdout.flush()
なかんじで。
コメントでの補足を受けて、追記しました
標準入出力のフラッシュとかcronジョブ特有の問題とかではなく、コードにエラーがある為にスクリプトの実行がされていないようです。Ubuntu17.04 + python3.5.3 で試した例を示します。
スクリプトをtest01.pyとして以下を用意します。(ダメ押しでflush
しています)
Python3
1# test01.py 2import time 3import sys 4 5print("test1", flush=True) 6print("test2", flush=True) 7sys.stdout.flush(); 8 9time.sleep(5) 10v = 1 11# cause exception 12print("str " + v) 13# syntax error 14print "test3"
これを実行すると、Syntax Errorが報告されるだけで、そもそも"test1"も"test2"も出力されません。コードが実行されていないのでしょう。(まぁ、当たり前と言えば当たり前)
Bash
1$ python3 test01.py 2 File "test01.py", line 13 3 print "test3" 4 ^ 5SyntaxError: Missing parentheses in call to 'print'
修正して、python3としては文法エラーである`print "test03"の部分だけコメントにし、実行します。
bash
1$ python test01.py 2test1 3test2 4Traceback (most recent call last): 5 File "test01.py", line 11, in <module> 6 print("str " + v) 7TypeError: Can't convert 'int' object to str implicitly
ランタイムエラーでExceptionは吐かれますが、"test1", "test2"は出力され、コードが実行されていることが分かります。要は、まず「python3のコードとして完成していなければならない。」が最低条件だと思います。そうすれば、can110さんに実際に試していただいたように出力されるようになるはずです。
おまけですが、py_compileモジュールで文法チェックだけする方法があります。
文法エラーのある状態でtest01.pyをコンパイルした例
Bash
1$ python3 -m "py_compile" test01.py 2 File "test01.py", line 13 3 print "test3" 4 ^ 5SyntaxError: Missing parentheses in call to 'print'
投稿2018/12/25 03:35
編集2018/12/25 05:39総合スコア9369
0
補足
test.sh 1>~
だとtest.sh
スクリプトが終了するまで書き込まれないようです。
以下のようにpython ~.py 1>~
のように直接.py
スクリプトを実行した結果をリダイレクトすると、所望の動作をします。
補足前の回答
当方ラズパイ
Linux rpi2 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l GNU/Linux
、
Python 3.5.3 (default, Sep 27 2018, 17:25:39) [GCC 6.3.0 20170516] on linux
で以下のソースにて順次ファイルに書き込まれることを確認しました。
なお、他の方も指摘されていますがprint "test"
の行でエラー発生しているものと思われます。
Python
1# hoge.py 2import time 3import sys 4for i in range(30): 5 sys.stderr.write('stderr:{}\n'.format(i)) 6 sys.stderr.flush() 7 print('print:{}'.format(i),flush=True) 8 time.sleep(1)
# cron 12 * * * * python3 /home/pi/hoge.py 1> hoge_out.log 2> hoge_err.log
投稿2018/12/25 04:19
編集2018/12/25 05:27総合スコア38352
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Pythonに限らず一般的に、プログラムからディスクファイルへの書き出しは一定サイズ溜まってからOSに書き込み要求が出ます。例えば8Kバイトとか。
(一方、端末への書き出しは、普通は改行で行われる)
プログラムで、OSへ書き込み要求が出るように指示するのは、dodox86 さんの回答の通り、flush
を行います。水洗トイレを流すときのボタンと同じ。
また、途中でエラーが出ると、それまでに出力されるはずだった標準出力は無視され、標準エラー出力のみ書き込まれます
これはちょっと考えづらいです。プログラムの終了時には、正常終了であれ、異常終了であれ、オープン中のファイルはクローズされるので、その時点で書き込まれるはずです。
(kill -9
で殺したとき以外)
何か特別なエラー処理を設定しているのでしょうか?
投稿2018/12/25 04:01
総合スコア86289
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/12/25 03:47
2018/12/25 04:06
2018/12/25 04:22
2018/12/25 04:46 編集
2018/12/25 05:43
2018/12/25 05:49
2018/12/25 05:52