如果可能,如何使用os.execv()使用管道和重定向?

时间:2017-10-06 05:18:28

标签: python

我从用户那里获取命令和参数,解析它们并将它们传递给os.execvp(),如下所示:

> ps -a -u -x

cmd = "ps"
args = ["-a", "-u", "-x"]
os.execvp(cmd, args)

问题是这不适用于管道或重定向,所以这样的事情不会起作用:

> ps -a -u -x > output.txt

cmd = ps
args = ["-a", "-u", "-x", ">", "output.txt"]
os.execvp(cmd, args)

我理解我的问题是>output.txt不是ps的参数,我只是不知道解决此问题的最佳方法。我希望我错过了正确的方法。

1 个答案:

答案 0 :(得分:3)

使用os.execv,我们处于操作系统的低级别。

要重定向输出,我们需要替换文件描述符号。执行命令前1(stdout)。

import os

STDOUT = 1

fdout = os.open('output.txt', os.O_WRONLY)
os.dup2(fdout, STDOUT)
os.execvp('ps', 'ps -a -u -x'.split())
# not reached
os._exit(127) # just for the case of execv failure

使用管道连接两个进程需要做更多的工作。管道有两端,必须先创建。然后fork将复制该过程。每个进程必须关闭管道的一端,并将另一端分别重定向到其stdin或stdout。

import os

STDIN = 0 
STDOUT = 1 

pipein, pipeout = os.pipe()
if os.fork():
    # parent
    os.close(pipeout)
    os.dup2(pipein, STDIN)
    os.execlp('wc', '-l')
    # not reached
    os._exit(127)
else:
    # child
    os.close(pipein)
    os.dup2(pipeout, STDOUT)
    os.execvp('ps', 'ps -a -u -x'.split())
    # not reached
    os._exit(127)

这些只是概念的例子。