我正在Windows上编写Python 3.6程序,以将所有输入记录到子进程中进行备份。 (由于实际程序是商业产品(exe文件),所以我无法修改子过程代码,而我没有源代码。)
我尝试了以下代码,但它不起作用。文本仅显示在终端中,用于记录的txt文件为空。
Main.py :
import subprocess
import sys
class dup_stream():
def __init__(self, original_stream, file):
self.original_stream = original_stream
self.log = open(file, 'a')
def write(self, message):
self.log.write(message)
self.original_stream.write(message)
def fileno(self):
return self.original_stream.fileno()
completed_process = subprocess.run('python Hello.py',
stdin=dup_stream(sys.stdin, 'stdin.txt'),
stderr=dup_stream(sys.stderr, 'stderr.txt'),
stdout=dup_stream(sys.stdout, 'stdout.txt'))
Hello.py :
name = input("Your name:") # e.g. "Jane Doe"
print('Hello,',name)
预期结果:
在终端中:
Your name: Jane Doe
Hello, Jane Doe
stdin.txt:
Jane Doe
stdout.txt:
Your name:
Hello, Jane Doe
我之前曾问过一个更普遍的问题(Capture inputs to subprocess.run()),但没有任何实际答案。
答案 0 :(得分:2)
subprocess
很可能会绕过此操作,因为它直接使用fileno
。
使用stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
。
但是,当时如何转发所有内容并非完全简单。也许最简单的方法是拥有3个线程,每个线程stdin
,stdout
和stderr
都从源中读取(例如sys.stdin
或{{1 }}),然后将其写入文件和目标(process.stdout
或process.stdin
)。
另请参见here。
答案 1 :(得分:0)
我遇到了一个类似的问题,该问题由包装器类解决,而不是通过sys.stdin传递(我只需要记录读取和读取行):
class StdinWrapper(object):
def __getattribute__(self, name):
attr = getattr(sys.stdin, name)
if name == 'readline' or name == 'read':
def method_with_log(*args, **kwargs):
result = attr(*args, **kwargs)
f = open('/tmp/log-input', 'a')
f.write(result)
f.close()
return result
return method_with_log
return attr