记录python子进程的语法错误和未捕获的异常,并将它们打印到终端
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了记录python子进程的语法错误和未捕获的异常,并将它们打印到终端,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3579字,纯文字阅读大概需要6分钟。
内容图文
问题
我一直在尝试编写一个程序来记录子进程的未捕获的异常和语法错误.容易,对吗?把stderr管道送到正确的地方.
但是,子进程是另一个python程序 – 我将其称为test.py-,它需要运行,就像它的输出/错误没有被捕获一样.也就是说,运行记录器程序需要看起来像用户正常运行python test.py.
进一步使问题复杂化的是the problem,如果不使用readline,raw_input实际上会被发送到stderr.不幸的是,我不能只导入readline,因为我无法控制使用我的错误记录器运行的文件.
笔记:
>我在这个代码运行的机器上相当受限制.我无法安装pexpect或编辑* customize.py文件(因为该程序将由许多不同的用户运行).我真的觉得应该有一个stdlib解决方案,但是…
>这只需要在mac上工作.
>这样做的动机是我是一个研究新程序员得到的错误的团队的一员.
我试过的
我尝试了以下方法,没有成功:
>只使用问题How do I write stderr to a file while using “tee” with a pipe?中的tee(未能生成raw_input提示);我在几个SO问题中发现的tee python实现有类似的问题
>覆盖sys.excepthook(无法使其适用于子进程)
> this question’s最佳答案似乎很有希望,但未能正确显示raw_input提示.
> logging module对于实际写入日志文件似乎很有用,但似乎没有解决问题的关键
>自定义stderr读者
>无休止的谷歌搜索
解决方法:
The tee-based answer that you’ve linked不太适合您的任务.虽然你可以通过使用-u选项来修复“raw_input()提示”问题来禁用缓冲:
errf = open('err.txt', 'wb') # any object with .write() method
rc = call([sys.executable, '-u', 'test.py'], stderr=errf,
bufsize=0, close_fds=True)
errf.close()
更合适的解决方案可能基于pexpect或pty,example.
running the logger program needs to seem like the user has just run python test.py as normal.
#!/usr/bin/env python
import sys
import pexpect
with open('log', 'ab') as fout:
p = pexpect.spawn("python test.py")
p.logfile = fout
p.interact()
你不需要安装pexpect它是纯Python你可以把它放在你的代码旁边.
这是一个基于tee的模拟(test.py以非交互方式运行):
#!/usr/bin/env python
import sys
from subprocess import Popen, PIPE, STDOUT
from threading import Thread
def tee(infile, *files):
"""Print `infile` to `files` in a separate thread."""
def fanout(infile, *files):
flushable = [f for f in files if hasattr(f, 'flush')]
for c in iter(lambda: infile.read(1), ''):
for f in files:
f.write(c)
for f in flushable:
f.flush()
infile.close()
t = Thread(target=fanout, args=(infile,)+files)
t.daemon = True
t.start()
return t
def call(cmd_args, **kwargs):
stdout, stderr = [kwargs.pop(s, None) for s in 'stdout', 'stderr']
p = Popen(cmd_args,
stdout=None if stdout is None else PIPE,
stderr=None if stderr is None else (
STDOUT if stderr is STDOUT else PIPE),
**kwargs)
threads = []
if stdout is not None:
threads.append(tee(p.stdout, stdout, sys.stdout))
if stderr is not None and stderr is not STDOUT:
threads.append(tee(p.stderr, stderr, sys.stderr))
for t in threads: t.join() # wait for IO completion
return p.wait()
with open('log','ab') as file:
rc = call([sys.executable, '-u', 'test.py'], stdout=file, stderr=STDOUT,
bufsize=0, close_fds=True)
有必要合并stdout / stderr,因为不清楚raw_input(),getpass.getpass()可能会打印其提示.
在这种情况下,线程也不是必需的:
#!/usr/bin/env python
import sys
from subprocess import Popen, PIPE, STDOUT
with open('log','ab') as file:
p = Popen([sys.executable, '-u', 'test.py'],
stdout=PIPE, stderr=STDOUT,
close_fds=True,
bufsize=0)
for c in iter(lambda: p.stdout.read(1), ''):
for f in [sys.stdout, file]:
f.write(c)
f.flush()
p.stdout.close()
rc = p.wait()
注意:最后一个示例和基于tee的解决方案不捕获getpass.getpass()提示符,但pexpect和基于pty的解决方案执行:
#!/usr/bin/env python
import os
import pty
import sys
with open('log', 'ab') as file:
def read(fd):
data = os.read(fd, 1024)
file.write(data)
file.flush()
return data
pty.spawn([sys.executable, "test.py"], read)
我不知道pty.spawn()是否适用于macs.
内容总结
以上是互联网集市为您收集整理的记录python子进程的语法错误和未捕获的异常,并将它们打印到终端全部内容,希望文章能够帮你解决记录python子进程的语法错误和未捕获的异常,并将它们打印到终端所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。