【问题标题】:How to pipe input to python line by line from linux program?如何从linux程序逐行将输入管道输入到python?
【发布时间】:2013-07-13 13:40:19
【问题描述】:

我想将ps -ef 的输出逐行传送到python。

我正在使用的脚本是这个(first.py) -

#! /usr/bin/python

import sys

for line in sys.argv:
   print line

不幸的是,“行”被分成了由空格分隔的单词。所以,例如,如果我这样做

echo "days go by and still" | xargs first.py

我得到的输出是

./first.py
days
go
by
and
still

如何编写脚本以使输出为

./first.py
days go by and still

?

【问题讨论】:

    标签: python pipe


    【解决方案1】:

    我建议不要使用命令行参数,而是从 标准输入 (stdin) 中读取。 Python 有一个简单的习惯用法来遍历 stdin 处的行:

    import sys
    
    for line in sys.stdin:
        sys.stdout.write(line)
    

    我的使用示例(上面的代码保存到iterate-stdin.py):

    $ echo -e "first line\nsecond line" | python iterate-stdin.py 
    first line
    second line
    

    用你的例子:

    $ echo "days go by and still" | python iterate-stdin.py
    days go by and still
    

    【讨论】:

    • 澄清一下:你的目标是用你的 Python 程序逐行读取一个程序的标准输出。您正在使用命令行,您建议使用管道将标准输出从第一个程序传输到您的第二个程序(这是有道理的)。然后,不是简单地从 Python 程序中的标准输入中读取,您更愿意在堆栈中包含第三个程序,该程序执行从标准输入到命令行参数的魔术转换,并可能多次调用您的 Python 程序并对输入进行分段(你知道xargs 是如何工作的吗?)?
    • 操作系统对程序可以处理的命令行参数的数量施加了限制。 xargs 确保由xargs 的第一个参数定义的程序永远不会使用超过此限制定义的参数来调用。如果需要,它只是多次调用程序,以便处理所有参数。因此,对于大型输入,您的 Python 程序可能会发生多次独立运行。通常,命令行参数不是提供大量输入数据的地方。
    • 好的。那将是灾难性的。
    • 你如何检查用户/调用者是否真的通过管道输入了一些东西或者只是输入了python ./python_iterate_stdin.py
    • 是否可以通过管道输入交互式 Python REPL?运行 echo "days go by and still" | pythonecho "days go by and still" | python -i 将流作为 python 脚本而不是标准输入。
    【解决方案2】:

    你想要的是popen,它可以像读取文件一样直接读取命令的输出:

    import os
    with os.popen('ps -ef') as pse:
        for line in pse:
            print line
            # presumably parse line now
    

    请注意,如果您想要更复杂的解析,则必须深入研究subprocess.Popen 的文档。

    【讨论】:

      【解决方案3】:

      另一种方法是使用input() 函数(代码适用于 Python 3)。

      while True:
              try:
                  line = input()
                  print('The line is:"%s"' % line)
              except EOFError:
                  # no more information
                  break
      

      答案与博士得到的答案的区别。 Jan-Philip Gehrcke 是现在每一行的末尾都没有换行符(\n)。

      【讨论】:

        【解决方案4】:

        我知道这确实过时了,但你可以试试

        #! /usr/bin/python
        import sys
        print(sys.argv, len(sys.argv))
        
        if len(sys.argv) == 1:
            message = input()
        else:
            message = sys.argv[1:len(sys.argv)]
        
        print('Message:', message)
        

        我因此对其进行了测试:

        $ ./test.py
        ['./test.py'] 1
        this is a test
        Message: this is a test
        
        $ ./test.py this is a test
        ['./test.py', 'this', 'is', 'a', 'test'] 5
        Message: ['this', 'is', 'a', 'test']
        
        $ ./test.py "this is a test"
        ['./test.py', 'this is a test'] 2
        Message: ['this is a test']
        
        $ ./test.py 'this is a test'
        ['./test.py', 'this is a test'] 2
        Message: ['this is a test']
        
        $ echo "This is a test" | ./test.py
        ['./test.py'] 1
        Message: This is a test
        

        或者,如果您希望消息每次都是一个字符串,那么

            message = ' '.join(sys.argv[1:len(sys.argv)])
        

        在第 8 行可以解决问题

        【讨论】:

          猜你喜欢
          • 2011-08-31
          • 1970-01-01
          • 1970-01-01
          • 2011-10-31
          • 2014-02-03
          • 1970-01-01
          • 1970-01-01
          • 2020-05-11
          • 1970-01-01
          相关资源
          最近更新 更多