【问题标题】:make python script behave same as linux cmd with resp. to IO redirect使用 resp 使 python 脚本的行为与 linux cmd 相同。到 IO 重定向
【发布时间】:2019-10-28 05:54:02
【问题描述】:

我有一个 python prog,我想在产生输出时表现得像 linux cmd。 prog 使用“print()”,当在 cmd 行上运行时,打印的内容在终端上清晰可见。当我启动带有 bash 输出重定向到文件的 prog 时,文件保持为空。我犯了什么错误?

程序的打印部分:

chktime = 0
chkper  = 10

while True:
    if time.time() - chktime > chkper:
        chktime = time.time() 
        diskusepct = get_asus_diskusepct()
        print('Asus tmpfs free: ' + diskusepct)
        if float(diskusepct) > 95.0:
            with open("asus_syslog.log", 'w') as sl:
                sl.write(get_asus_syslog())
    else:
        print('Wait')
        time.sleep(1)

从 cmd 行(如预期):

rpi4b:~/python $ ./asus_diskwatch_v1.0.py 
Asus tmpfs free: 1
Wait
Wait
Wait
Wait

使用重定向(意外):

~/python $ ./asus_diskwatch_v1.0.py > asus_diskwatch.log &
[2] 4415
~/python $ cat asus_diskwatch.log
<nothing>

非常感谢您的反馈。

【问题讨论】:

    标签: python redirect printing


    【解决方案1】:

    这里发生的是输出缓冲。当打印输出定向到文件时,会收集一定数量的数据,直到它实际写入文件。如果您等待的时间足够长,您会注意到文件突然有大量“等待”行。 (如果您想对此进行测试,请将输出长度设置为数百个字符,这样您就不必等待这么长时间)。 请参阅有关控制缓冲的方法的问题:Disable output buffering

    【讨论】:

      【解决方案2】:

      要解决您的问题,我认为您需要做两件事:

      • 您需要将写入模式从 write 'w' 更改为 append'a',因为写入模式会覆盖之前的行,而追加模式会追加新行。

      • 您需要将缓冲区大小设置为1,因为默认缓冲区大小为8192

      所以,你的代码应该是这样的:

      chktime = 0
      chkper  = 10
      
      while True:
          if time.time() - chktime > chkper:
              chktime = time.time() 
              diskusepct = get_asus_diskusepct()
              print('Asus tmpfs free: ' + diskusepct)
              if float(diskusepct) > 95.0:
                  with open("asus_syslog.log", 'a', buffering=1) as sl: # <-- changes here
                      sl.write(get_asus_syslog())
          else:
              print('Wait')
      

      希望这能解决您的问题!

      【讨论】:

      • (删除了我对附加标志的坏评论 - 没有仔细查看您的答案)
      • 如您所见,每次if 条件成立时,它都会在写入模式 下创建一个文件,该文件会覆盖之前的内容。在while 循环之外创建文件应该可以解决问题,但追加模式 也应该可以解决问题。
      • @ErkkiRuohtula,您不必这样做,完全可以:)
      • 当然,我注意到我评论错了,附加标志对于单独编写的日志文件是必需的。
      • if 条件的目的实际上是从我的路由器中捕获 syslog 文件并存储一次。实际上,那里应该有一些 break 或 exit cmd。路由器某处存在内存泄漏,一旦内部闪存填满,它就会崩溃。华硕至今无能为力。所以我的想法是编写这个脚本来观察闪存是否接近 100% 满,然后获取系统日志以查看最后做了什么(向华硕抱怨),然后可能会向我发送一封警告电子邮件,或者重新启动路由器自动。不确定实时路由器上的 rm -rf /tmp 是否是个好主意。
      猜你喜欢
      • 2017-03-11
      • 1970-01-01
      • 2018-01-11
      • 2021-05-12
      • 1970-01-01
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 2021-01-19
      相关资源
      最近更新 更多