如何在bash中使python脚本"可管理"?

gbr*_*gbr 52 python pipe

我写了一个脚本,我希望它可以在bash中管道化.就像是:

echo "1stArg" | myscript.py
Run Code Online (Sandbox Code Playgroud)

可能吗?怎么样?

kha*_*hik 69

看到这个简单echo.py:

import sys

if __name__ == "__main__":
    for line in sys.stdin:
        sys.stderr.write("DEBUG: got line: " + line)
        sys.stdout.write(line)
Run Code Online (Sandbox Code Playgroud)

运行:

ls | python echo.py 2>debug_output.txt | sort
Run Code Online (Sandbox Code Playgroud)

输出:

echo.py
test.py
test.sh
Run Code Online (Sandbox Code Playgroud)

debug_output.txt内容:

DEBUG: got line: echo.py
DEBUG: got line: test.py
DEBUG: got line: test.sh
Run Code Online (Sandbox Code Playgroud)

  • 写循环的方式(`while True` ...)既错误又肯定不是pythonic.实际上,空输入行将打破循环.一个简单而标准的解决方案是使用`for line in sys.stdin`读取标准输入.另外,最初的`line =''`是完全多余的. (4认同)
  • 大!我冒昧地用标准的4个空格缩进你的代码(参见PEP 8)而不是你使用的原始2个空格. (2认同)

tok*_*and 18

我将使用一个grep示例来补充其他答案,该示例使用fileinput来实现UNIX工具的典型行为:1)如果没有特定文件,则从stdin读取数据; 2)许多文件可以作为参数发送; 3)-表示stdin.

import fileinput
import re
import sys

def grep(lines, regexp):
    return (line for line in lines if regexp.search(line))

def main(args):
    if len(args) < 1:
        print("Usage: grep.py PATTERN [FILE...]", file=sys.stderr)
        return 2 
    regexp = re.compile(args[0])
    input_lines = fileinput.input(args[1:])
    for output_line in grep(input_lines, regexp):
        sys.stdout.write(output_line)

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
Run Code Online (Sandbox Code Playgroud)

例:

$ seq 1 20 | python grep.py "4"
4
14
Run Code Online (Sandbox Code Playgroud)


NPE*_*NPE 11

在您的Python脚本中,您只需阅读stdin.


x13*_*13n 5

从 stdin 读取的所有内容都是“可管道化的”。管道只是将前一个程序的标准输出重定向到后者。