Python paho MQTT loop_forvers():如何在脚本运行时将输出重定向到文件



我正在运行一个脚本来订阅MQTT代理的主题并获取与它们相关的数据。我这样运行脚本:

$ python3 test_mqtt_client.py

import paho.mqtt.client as paho
import ssl
import random
from config import BROKER_ADDRESS, PORT, CLIENT_CERT, CLIENT_KEY, CA_KEY, SUBSCRIBED_TOPICS, DEST_FOLDER
#"on_message" callback
def on_message(client, userdata, message):

print("received message =",str(message.payload.decode("utf-8")))

filename = str(random.randint(0,4294967295))
file = open(DEST_FOLDER + filename + '.json', 'w+')
file.write(str(message.payload.decode("utf-8")))
file.close()

client=paho.Client() 
client.on_message=on_message
print("connecting to broker")
client.tls_set(
CA_KEY,
certfile=CLIENT_CERT,
keyfile=CLIENT_KEY,
cert_reqs=ssl.CERT_REQUIRED,
tls_version=ssl.PROTOCOL_TLSv1_2,
ciphers=None
)
client.tls_insecure_set(True)
client.connect(BROKER_ADDRESS, PORT, 60)
for x in SUBSCRIBED_TOPICS:
client.subscribe(x)
print('Subscribed to topic "' + x + '".')
client.loop_forever()
time.sleep(1)

问题是:如果我试图输出到这样的文件:

$ python3 test_mqtt_client.py >> /tmp/test_mqtt_client.log

我不会得到文件上的任何内容,直到我用Ctrl+C中断脚本。

当脚本运行时,如何在/tmp/test_mqtt_client.log中获得脚本的输出?我的意思是,在打断它之前。

默认情况下,stdout的输出是缓冲的:这意味着在输出缓冲区满之前,它实际上不会被刷新到文件中,这反过来意味着,当将stdout重定向到文件时,在代码生成足够的输出以溢出输出缓冲区时,通常不会在文件中看到任何内容。

有多种方法可以处理这种行为:

  1. 只输出到stderr,而不是stdoutstderr默认情况下不缓冲,您应该立即看到输出。这是例如logging模块的默认行为,对于记录长时间运行程序的输出,这通常比print更好。当然,您可以在print命令中设置file=sys.stderr

    print("this is a test", file=sys.stderr)
    

    (如果执行此操作,请记住在命令行上重定向stderr,而不是stdout。)

  2. 您可以在无缓冲模式下运行Python,方法是在命令行中添加-u标志:

    python -u test_mqtt_client.py >> test_mqtt_client.log
    
  3. 您可以在每次print语句后显式刷新输出缓冲区:

    print("some log message")
    sys.stdout.flush()
    

最新更新