使用 subprocess.Popen 输出重定向到文件
Output redirection to file using subprocess.Popen
我有一个程序 script.out,我需要针对 10 个文件 运行 并将它们的输出重定向到 10 个文件。
我正在使用 subprocess.Popen()
来完成这项工作,但在重定向标准输出流时似乎遇到了一些错误。
...
for i in range(10):
data = subprocess.Popen([ script.out, "<", input_file[i], ">", output_file[i]])
对于解决方法,我直接使用 os.system()
到 运行。但是我想知道为什么 subprocess.Popen()
进程在那里失败了?
I/O <
和 >
的重定向由 shell 完成。当您调用 subprocess.Popen()
并将列表作为第一个参数或不使用 shell=True
时,程序将直接执行,而不使用 shell 来解析命令行。因此,您正在执行程序并将文字参数 <
和 >
传递给它。就好像你执行了 shell 命令并引用了 <
和 >
字符:
scriptname '<' infile.txt '>' outfile.txt
如果你想使用 shell 你必须发送一个字符串(就像使用 os.system()
.
data = subprocess.Popen(" ".join([ shlex.quote(script.out), "<", shlex.quote(input_file[i]), ">", shlex.quote(output_file[i])]), shell=True)
使用 shlex.quote()
转义不应被视为 shell 元字符的参数。
在 subprocess.Popen
参数中使用 '<' 或 '>' 而不传递 shell=True
将不会有任何效果,因为输入重定向是 shell 的一项功能。如果你处理不受信任的数据(即 shell 注入),那么传递 shell=True
确实有一些安全考虑,所以我不建议你为你的这个特定任务走这条路。您可以在这里阅读更多内容:https://docs.python.org/3/library/subprocess.html#security-considerations
您任务的简单解决方案是在创建 subprocess.Popen
对象时使用 stdout
参数:
import subprocess
with open('output.txt', 'w') as f:
p = subprocess.Popen(['/path/to/executable', 'arg1'], stdout=f)
stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object, and None. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the applications should be captured into the same file handle as for stdout.
我有一个程序 script.out,我需要针对 10 个文件 运行 并将它们的输出重定向到 10 个文件。
我正在使用 subprocess.Popen()
来完成这项工作,但在重定向标准输出流时似乎遇到了一些错误。
...
for i in range(10):
data = subprocess.Popen([ script.out, "<", input_file[i], ">", output_file[i]])
对于解决方法,我直接使用 os.system()
到 运行。但是我想知道为什么 subprocess.Popen()
进程在那里失败了?
I/O <
和 >
的重定向由 shell 完成。当您调用 subprocess.Popen()
并将列表作为第一个参数或不使用 shell=True
时,程序将直接执行,而不使用 shell 来解析命令行。因此,您正在执行程序并将文字参数 <
和 >
传递给它。就好像你执行了 shell 命令并引用了 <
和 >
字符:
scriptname '<' infile.txt '>' outfile.txt
如果你想使用 shell 你必须发送一个字符串(就像使用 os.system()
.
data = subprocess.Popen(" ".join([ shlex.quote(script.out), "<", shlex.quote(input_file[i]), ">", shlex.quote(output_file[i])]), shell=True)
使用 shlex.quote()
转义不应被视为 shell 元字符的参数。
在 subprocess.Popen
参数中使用 '<' 或 '>' 而不传递 shell=True
将不会有任何效果,因为输入重定向是 shell 的一项功能。如果你处理不受信任的数据(即 shell 注入),那么传递 shell=True
确实有一些安全考虑,所以我不建议你为你的这个特定任务走这条路。您可以在这里阅读更多内容:https://docs.python.org/3/library/subprocess.html#security-considerations
您任务的简单解决方案是在创建 subprocess.Popen
对象时使用 stdout
参数:
import subprocess
with open('output.txt', 'w') as f:
p = subprocess.Popen(['/path/to/executable', 'arg1'], stdout=f)
stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object, and None. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the applications should be captured into the same file handle as for stdout.