读取日志文件中的最后一条错误消息
Reading last error message in log file
在Python 2.7中,我在某个循环中有以下代码
file = open("log.txt", 'a+')
last_position = file.tell()
subprocess.Popen(["os_command_producing_error"], stderr = file)
file.seek(last_position)
error = file.read()
print(error) # example of some action with the error
目的是让 stderr
刚刚给出的错误得到打印,而 file
保留整个记录。
我是 Python 的初学者,我不清楚 stderr = file
中发生了什么。
我的问题是 error
一直是空的,尽管 file
中不断记录错误。
有人可以解释为什么吗?
我试过在 subprocess
行之后再次添加关闭和打开文件,或者 file.flush()
。但是还是一样的效果。
编辑: 下面答案中的代码对我来说很有意义,它似乎适用于 post 的作者。对我来说(在 Windows 中)它不起作用。它给出一个空 err
和一个空文件 log.txt
。如果我 运行 它逐行(例如调试)它确实有效。如何理解和解决这个问题?
编辑: 我将 Popen
更改为 call
,现在可以使用了。我想 call
等待 subprocess
完成才能继续脚本。
尝试以下代码:
file = open("log.txt", 'a+')
sys.stderr = file
last_position = file.tell()
try:
subprocess.call(["os_command_producing_error"])
except:
file.close()
err_file = open("log.txt", 'r')
err_file.seek(last_position)
err = err_file.read()
print err
err_file.close()
sys.stderr
映射标准错误消息,如 sys.stdout
(映射标准输出)和 sys.stdin
(映射标准输入)。
这会将标准错误映射到 file
。所以所有的标准错误都将写入文件 log.txt
.
error
为空,因为您在进程有机会向文件写入任何内容之前读取得太早。 Popen()
启动一个新进程;它不会等待它完成。
call()
等同于等待子进程退出的 Popen().wait()
这就是为什么在这种情况下你应该看到非空 error
(如果子进程确实写stderr
).
的任何内容
#!/usr/bin/env python
import subprocess
with open("log.txt", 'a+') as file:
subprocess.check_call(["os_command_producing_error"], stderr=file)
error = file.read()
print(error)
你应该小心mixing buffered (.read()
) and unbuffered I/O (subprocess
)。
这里不需要外部文件,读取错误:
#!/usr/bin/env python
import subprocess
error = subprocess.check_output(["os_command_producing_error"],
stderr=subprocess.STDOUT)
print(error)
它合并了 stderr 和 stdout 以及 returns 输出。
如果您不想捕获标准输出然后只获取标准错误,您可以使用 Popen.communicate()
:
#!/usr/bin/env python
import subprocess
p = subprocess.Popen(["os_command_producing_error"], stderr=subprocess.PIPE)
error = p.communicate()[1]
print(error)
您可以捕获 stderr 并将其附加到文件中:
#!/usr/bin/env python
import subprocess
error = bytearray()
p = subprocess.Popen(["os_command_producing_error"],
stderr=subprocess.PIPE, bufsize=1)
with p.stderr as pipe, open('log.txt', 'ab') as file:
for line in iter(pipe.readline, b''):
error += line
file.write(line)
p.wait()
print(error)
参见 Python: read streaming input from subprocess.communicate()。
在Python 2.7中,我在某个循环中有以下代码
file = open("log.txt", 'a+')
last_position = file.tell()
subprocess.Popen(["os_command_producing_error"], stderr = file)
file.seek(last_position)
error = file.read()
print(error) # example of some action with the error
目的是让 stderr
刚刚给出的错误得到打印,而 file
保留整个记录。
我是 Python 的初学者,我不清楚 stderr = file
中发生了什么。
我的问题是 error
一直是空的,尽管 file
中不断记录错误。
有人可以解释为什么吗?
我试过在 subprocess
行之后再次添加关闭和打开文件,或者 file.flush()
。但是还是一样的效果。
编辑: 下面答案中的代码对我来说很有意义,它似乎适用于 post 的作者。对我来说(在 Windows 中)它不起作用。它给出一个空 err
和一个空文件 log.txt
。如果我 运行 它逐行(例如调试)它确实有效。如何理解和解决这个问题?
编辑: 我将 Popen
更改为 call
,现在可以使用了。我想 call
等待 subprocess
完成才能继续脚本。
尝试以下代码:
file = open("log.txt", 'a+')
sys.stderr = file
last_position = file.tell()
try:
subprocess.call(["os_command_producing_error"])
except:
file.close()
err_file = open("log.txt", 'r')
err_file.seek(last_position)
err = err_file.read()
print err
err_file.close()
sys.stderr
映射标准错误消息,如 sys.stdout
(映射标准输出)和 sys.stdin
(映射标准输入)。
这会将标准错误映射到 file
。所以所有的标准错误都将写入文件 log.txt
.
error
为空,因为您在进程有机会向文件写入任何内容之前读取得太早。 Popen()
启动一个新进程;它不会等待它完成。
call()
等同于等待子进程退出的 Popen().wait()
这就是为什么在这种情况下你应该看到非空 error
(如果子进程确实写stderr
).
#!/usr/bin/env python
import subprocess
with open("log.txt", 'a+') as file:
subprocess.check_call(["os_command_producing_error"], stderr=file)
error = file.read()
print(error)
你应该小心mixing buffered (.read()
) and unbuffered I/O (subprocess
)。
这里不需要外部文件,读取错误:
#!/usr/bin/env python
import subprocess
error = subprocess.check_output(["os_command_producing_error"],
stderr=subprocess.STDOUT)
print(error)
它合并了 stderr 和 stdout 以及 returns 输出。
如果您不想捕获标准输出然后只获取标准错误,您可以使用 Popen.communicate()
:
#!/usr/bin/env python
import subprocess
p = subprocess.Popen(["os_command_producing_error"], stderr=subprocess.PIPE)
error = p.communicate()[1]
print(error)
您可以捕获 stderr 并将其附加到文件中:
#!/usr/bin/env python
import subprocess
error = bytearray()
p = subprocess.Popen(["os_command_producing_error"],
stderr=subprocess.PIPE, bufsize=1)
with p.stderr as pipe, open('log.txt', 'ab') as file:
for line in iter(pipe.readline, b''):
error += line
file.write(line)
p.wait()
print(error)
参见 Python: read streaming input from subprocess.communicate()。