有没有办法在Python中执行等效的UNIX命令行tee?我正在做一个典型的fork/exec模式,我希望来自子节点的stdout同时出现在日志文件和父节点的stdout上,而不需要任何缓冲.
例如,在这个python代码中,子进程的stdout最终出现在日志文件中,但不在父进程的stdout中.
pid = os.fork()
logFile = open(path,"w")
if pid == 0:
os.dup2(logFile.fileno(),1)
os.execv(cmd)
Run Code Online (Sandbox Code Playgroud)
编辑:我不想使用子进程模块.我正在用子进程做一些复杂的事情,需要我fork手动调用.
在下文中,SOMEPATH是子可执行文件的路径,格式适合subprocess.Popen(参见其文档).
import sys, subprocess
f = open('logfile.txt', 'w')
proc = subprocess.Popen(SOMEPATH, stdout=subprocess.PIPE)
while True:
out = proc.stdout.read(1)
if out == '' and proc.poll() != None:
break
if out != '':
# CR workaround since chars are read one by one, and Windows interprets
# both CR and LF as end of lines. Linux only has LF
if out != '\r': f.write(out)
sys.stdout.write(out)
sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
在这里,您可以使用不使用该subprocess模块的工作解决方案 虽然,您可以将它用于tee进程,同时仍然使用exec*自定义子进程的函数套件(只需使用stdin=subprocess.PIPE然后将描述符复制到stdout).
import os, time, sys
pr, pw = os.pipe()
pid = os.fork()
if pid == 0:
os.close(pw)
os.dup2(pr, sys.stdin.fileno())
os.close(pr)
os.execv('/usr/bin/tee', ['tee', 'log.txt'])
else:
os.close(pr)
os.dup2(pw, sys.stdout.fileno())
os.close(pw)
pid2 = os.fork()
if pid2 == 0:
# Replace with your custom process call
os.execv('/usr/bin/yes', ['yes'])
else:
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
pass
Run Code Online (Sandbox Code Playgroud)
请注意,该tee命令在内部执行与Ben在其答案中建议的相同:读取输入并在写入时循环输出文件描述符.它可能更有效,因为优化的实现,因为它是用C编写的,但是你有不同管道的开销(不知道哪个解决方案更有效,但在我看来,重新分配自定义文件对象stdout是一个更优雅的解决方案).
更多资源:
| 归档时间: |
|
| 查看次数: |
2550 次 |
| 最近记录: |