【问题标题】:Capture stdout stderr of python subprocess, when it runs from cron or rc.local从 cron 或 rc.local 运行时捕获 python 子进程的 stdout stderr
【发布时间】:2014-10-14 10:13:57
【问题描述】:

当我通过 cron 或 rc.local

进行午餐时访问命令的输出 (stderr stdout) 时遇到问题

它在常规 shell 中完美运行,但通过 rc.local 失败

cat /root/watchdog.py 
import subprocess
    cmd = ( 'echo "TEST" |gnokii --config /root/.config/gnokii/config --sendsms +123456789xx ')
    #p = subprocess.Popen([cmd, '2>&1'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
    p = subprocess.Popen([cmd, '2>&1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    output = p.stdout.read()
    output += p.stderr.read()
    logFile = open("/root/logfile", 'a+')
    ##### 
    #Idea to read line by line:
    #output = ''
    #    for line in iter(p.stdout.readline,''):
    #       print "captured line: %s" % line.rstrip()
    #       #logFile.write(line.rstrip())
    #       output += line
    logFile.write(output)
    logFile.close()

从控制台运行时的输出如下:

/root/watchdog.py 
GNOKII Version 0.6.30
Cannot open logfile /root/.cache/gnokii/gnokii-errors
WARNING: cannot open logfile, logs will be directed to stderr
Send succeeded with reference 186!

在我的 rc.local 中

/root/watchdog.py  > /root/mywatchPY.out 2>&1 & 

这看起来很有趣: Redirect subprocess stderr to stdout 但这并不能解决问题。

知道如何在没有完整外壳的情况下捕获子进程运行的 sdterr/stdout 吗?

【问题讨论】:

    标签: python cron subprocess stdout


    【解决方案1】:

    您的代码中有多个问题:

    • shell=True 时将命令及其参数作为字符串传递,否则参数将传递给shell 本身而不是命令
    • 如果您打算将后者应用于整个管道,而不仅仅是其中的最后一个命令,则应该使用 stderr=subprocess.STDOUT 而不是 2>&1
    • 使用p.communicate() 而不是p.stdout.read()p.stderr.read(),否则如果任何操作系统管道缓冲区填满,子进程可能会停止
    • 如果要将输出重定向到文件,则无需先将其保存为字符串
    import shlex
    from subprocess import Popen, PIPE, STDOUT
    
    with open("/root/logfile", 'ab', 0) as logfile:
        p = Popen(shlex.split('gnokii ... +123456789xx'), 
                  stdin=PIPE, stdout=logfile, stderr=STDOUT)
        p.communicate(b'TEST')
    

    Redirect subprocess stderr to stdout 不适用,因为您明确重定向 stdout

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      相关资源
      最近更新 更多