How to make a python script “pipeable” in bash?

前端 未结 4 1601
轮回少年
轮回少年 2020-12-04 16:08

I wrote a script and I want it to be pipeable in bash. Something like:

echo \"1stArg\" | myscript.py

Is it possible? How?

相关标签:
4条回答
  • 2020-12-04 17:01

    See this simple echo.py:

    import sys
    
    if __name__ == "__main__":
        for line in sys.stdin:
            sys.stderr.write("DEBUG: got line: " + line)
            sys.stdout.write(line)
    

    running:

    ls | python echo.py 2>debug_output.txt | sort
    

    output:

    echo.py
    test.py
    test.sh
    

    debug_output.txt content:

    DEBUG: got line: echo.py
    DEBUG: got line: test.py
    DEBUG: got line: test.sh
    
    0 讨论(0)
  • 2020-12-04 17:01

    In your Python script you simply read from stdin.

    0 讨论(0)
  • 2020-12-04 17:07

    Everything that reads from stdin is "pipeable". Pipe simply redirects stdout of former program to the latter.

    0 讨论(0)
  • 2020-12-04 17:08

    I'll complement the other answers with a grep example that uses fileinput to implement the typical behaviour of UNIX tools: 1) if no arguments are specified, it reads data from stdin; 2) many files can be specified as arguments; 3) a single argument of - means 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:]))
    

    Example:

    $ seq 1 20 | python grep.py "4"
    4
    14
    
    0 讨论(0)
提交回复
热议问题