当我通过 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 但它没有解决问题。
任何想法如何捕获没有完整shell的子进程运行的sdterr / stdout?
答案 0 :(得分:1)
您的代码中存在多个问题:
shell=True
时将命令及其args作为字符串传递,否则args将传递给shell本身而不是命令stderr=subprocess.STDOUT
而不是2>&1
p.communicate()
而不是p.stdout.read()
,p.stderr.read()
否则如果任何OS管道缓冲区填满,子进程可能会停止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
。