How to make a python script "pipeable" in bash?
See this simple echo.py
:
import sysif __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.pytest.pytest.sh
debug_output.txt content:
DEBUG: got line: echo.pyDEBUG: got line: test.pyDEBUG: got line: test.sh
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 fileinputimport reimport sysdef 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"414