用Python cmd模块实现Unix管道?

4 投票
4 回答
1096 浏览
提问于 2025-04-17 04:48

我正在用Python的 cmd 模块实现一个简单的命令行工具。
现在,我想在这个命令行工具中实现一个Unix管道,也就是说,当我输入:

ls | grep "a"  

时,它会把 do_ls 的结果传递给 do_grep 的输入。
请问,最简单的方法是什么?
抱歉,CryptoJones,我忘了说我的平台是Windows。

4 个回答

2

最简单的方法可能就是把你用 do_ls 得到的结果存到一个缓冲区里,然后再把这些结果传给 do_grep。你可能想要逐行处理或者按几行一组来处理,而不是一次性处理所有内容,特别是如果你想实现一个 more 命令的话。

一个更全面的做法是把所有命令放在子进程中运行,并依赖现有的标准库模块来支持管道,比如 subprocess

2

你可能想用一下 cmd2 这个模块。它是 cmd 的升级版,功能更多。

可以看看它的文档中关于 输出重定向 的部分。

3

这里有一个简单的例子,可能会对你有帮助:

from cmd import Cmd

class PipelineExample(Cmd):

    def do_greet(self, person):
        if person:
            greeting = "hello, " + person
        else:
            greeting = 'hello'
        self.output = greeting

    def do_echo(self, text):
        self.output = text

    def do_pipe(self, args):
        buffer = None
        for arg in args:
            s = arg
            if buffer:
                # This command just adds the output of a previous command as the last argument
                s += ' ' + buffer
            self.onecmd(s)
            buffer = self.output

    def postcmd(self, stop, line):
        if hasattr(self, 'output') and self.output:
            print self.output
            self.output = None
        return stop

    def parseline(self, line):
        if '|' in line:
            return 'pipe', line.split('|'), line
        return Cmd.parseline(self, line)

    def do_EOF(self, line):
        return True

if __name__ == '__main__':
    PipelineExample().cmdloop()

下面是一个示例会话:

(Cmd) greet wong
hello, wong
(Cmd) echo wong | greet
hello, wong
(Cmd) echo wong | greet | greet
hello, hello, wong

撰写回答