繁体   English   中英

在Python中解决进程链

[英]Solving process chaining in Python

我正在尝试编写一个实用程序,它将在Python中无缝管理无限量的命令。 这是我到目前为止所提出的,遵循subprocess管道的文档

from subprocess import Popen, PIPE, STDOUT

def taskchain(argset, result=STDOUT):
    lastprocess = None

    for index, args in enumerate(argset): # expected to be a list containing lists
        process = Popen(args, stdout=stdout if index == (len(argset)-1) else PIPE,
            stdin=None if lastprocess is None else lastprocess.stdout)

        if lastprocess is not None:
            lastprocess.stdout.close()

        lastprocess = process

    if stdout == PIPE:
        return lastprocess.communicate()[0]
    else:
        lastprocess.wait()

请注意,我没有使用shell=True ,以期避免出现安全问题。

不幸的是,这不起作用,因为我得到:

OSError: [Errno 9] Baf file descriptor

我不确定什么似乎失败了。 有人可以帮我写一个方法来实现无限量子进程的进程链接吗?

(用例是这样的: taskchain([('ps', 'aux'), ('grep', 'python'), ('cut', '-b', '1')]) 。)

stdout=stdout if argset.index(args) == (len(args) - 1) else PIPE)

这应该是

stdout=stdout if argset.index(args) == (len(argset) - 1) else PIPE)

你最好使用enumerate而不是argset.index

此外,您需要将子进程相互连接:

..., stdin=None if lastprocess is None else lastprocess.stdout)

最后, STDOUT仅作为stderr参数的参数有效; 传递stdout应该传递stdout=None

在@ ecatmur的帮助下,这是最终的解决方案:

def taskchain(*args, **kwargs):
    output = kwargs.get('output', PIPE)
    error_output = kwargs.get('error_output', STDOUT) 
    lastprocess = None

    for index, argset in enumerate(args):
        islastprocess = index == len(args) - 1

        process = Popen(argset, stdout=output if islastprocess else PIPE,
                stdin=None if lastprocess is None else lastprocess.stdout,
                stderr=error_output)

        if lastprocess is not None:
            lastprocess.stdout.close()

        lastprocess = process

    if output == PIPE:
        return lastprocess.communicate()
    else:
        lastprocess.wait()

流程链接在一起,有效地模拟基于壳的管道而没有安全风险!

例子:

>>> print taskchain(('ps','aux'), ('grep','python'), ('cut','-c','1-50'))[0].trim()
naftuli   3221  0.1  0.1  60960 12376 pts/3    S+ 
naftuli   3242  0.0  0.0  32592  5748 pts/2    S+ 
naftuli   3246  0.0  0.0   9388   916 pts/2    S+ 
naftuli   5852  0.0  0.2 430284 20200 ?        Sl 
root      8153  0.0  0.1  95520 11060 ?        S

>>> print taskchain(('ls',), ('grep', 'ic'))[0]
Music
Pictures
Public

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM