簡體   English   中英

Nohup和Python -u:它仍然不會實時記錄數據

[英]Nohup and Python -u : it still doesn't log data in realtime

在后台啟動Python進程時,用

nohup python myscript.py > test.log 2>&1 < /dev/null &

問題是stdout是緩沖的:數據不是實時寫入test.log 這個問題的常見解決方案是使用sys.stdout.flush() 定期刷新 ,或者甚至更好,如本答案所示 ,使用python -u

nohup python -u myscript.py > test.log 2>&1 < /dev/null &

但這還不夠 我注意到它在幾個小時內工作,然后,它停止工作, 即幾個小時后test.log不再實時編寫,即使我使用nohup python -u ...

1) 這是如何重現問題 (我有一個標准的Debian Jessie)。 啟動此文件:

import time
import datetime
while True:
    print datetime.datetime.now()
    time.sleep(60)

nohup python -u myscript.py > test.log 2>&1 < /dev/null & 日志文件將在幾個小時內更新,然后在3或4小時后更新,不再有任何內容

2) 如何解決這個問題 ,而不必在代碼中每2行插入stdout.flush() (丑陋的解決方案)?

如果python -u似乎不適合你,下一個建議是將sys.stdout替換為不緩沖輸出的自定義類。

Magnus Lycka在郵件列表中提供了此解決方案

class Unbuffered(object):
    def __init__(self, stream):
        self.stream = stream
    def write(self, data):
        self.stream.write(data)
        self.stream.flush()
    def __getattr__(self, attr):
        return getattr(self.stream, attr)

import sys
sys.stdout = Unbuffered(sys.stdout)
print 'Unbuffered Output'

我不明白為什么python -u不適用於你的例子,但這應該為你解決問題。

有多種方法可以解決這個問題。

  1. 創建自己的非緩沖輸出函數並使用它而不是print()
import sys

def log(msg):
    sys.stdout.write(msg)
    sys.stdout.flush()

log("Hello World!")
  1. 使用mkfifo命令創建自己的日志記錄設備並寫入它而不是stdout。 使用單獨的命令將設備從管道傳輸到文件。

  2. 直接寫日志文件並在執行時刷新。 與第一名相同,但完全避免使用stdout。 這就是我要做的。

我會懷疑nohup。 終端打開標准的i / o流並將它們傳遞給進程。 如果您使用nohup運行進程然后注銷並關閉終端,我不確定標准流會發生什么。 可能是操作系統會進行某種垃圾收集並關閉它們而不會使用stdout。 你應該考慮編寫自己的日志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM