假设我创建了一个subprocess
import subprocess
ps = subprocess.Popen(command, shell=True)我希望将新进程的输出重定向到名为x.log的文件中,其中x是创建的进程的pid。
这是怎么做到的?
我尝试在远程服务器上运行多个进程,每个进程需要几天的时间才能完成。我希望能够查看在创建它们的脚本完成运行后仍在运行的进程的进度,因此我需要它们在文件中的输出,以及理解哪个pid生成哪个文件的能力。
目前,我正在创建进程之前绘制一个随机数r,将其输出重定向到r.log,并维护pids与其输出文件之间的映射。这似乎很愚蠢,因为我所需要的只是让进程将其输出重定向到一个名为进程pid的文件。
发布于 2015-10-23 09:48:25
stdout和stderr参数的subprocess.Popen允许您将标准输出重定向到不同类型的流。
stdin、stdout和stderr分别指定执行程序的标准输入、标准输出和标准错误文件句柄。有效值是管道、现有文件描述符(正整数)、现有文件对象和无。..。子文件句柄将从父进程继承。另外,stderr可以是STDOUT,这意味着来自子进程的stderr数据应该被捕获到与stdout相同的文件句柄中。
您可能想尝试将输出重定向到这里的文件,但是您将没有子进程的pid来正确命名输出文件。
如果您的脚本在Unix上运行,您还可以尝试将一个可调用的对象传递给Popen的参数preexec_fn,该参数将用文件处理程序替换默认的输出流。使用此解决方案,您实际上可以使用os.getpid获得当前进程pid。
如果preexec_fn设置为可调用对象,则在执行子进程之前将在子进程中调用该对象。(仅Unix)
我用preexec_fn解决方案做了一些测试,只是替换sys.stdout就不起作用了。但doing it at the file descriptor level似乎有效。
def redirect_output():
import sys, os
# The opened file needs to stay alive
redirect_output._file = open('{}.log'.format(os.getpid()), 'w')
os.dup2(redirect_output._file.fileno(), sys.stdout.fileno())
sub = subprocess.Popen(['ls'], preexec_fn=redirect_output)当然,这是一个快速的例子,可能需要一些抛光。
上面的示例似乎在shell = False时正常工作,但在shell = True的情况下,您可以得到shell的pid。解决这个问题的一种方法是使用bash和exec来运行命令。
command = 'python -c "import os; print \'\\\'\'process: \'\\\'\', os.getpid()"'
sub = subprocess.Popen(["bash -c 'exec {} > $$.log'".format(command)],
shell = True,
preexec_fn = os.setsid
)
print 'Shell: ', sub.pid在这里,os.setsid用于正确地处理派生进程的终止。
发布于 2015-10-23 08:08:42
尝试在您的python代码中使用"currentSubProcess = subprocess.check_output("your“)。这样,"currentSubProcess“将包含子进程的输出,并且可以将其写入日志文件中。
https://stackoverflow.com/questions/33297241
复制相似问题