While I was searching ways to implement pipeline input for my python apps, I read an article from linuxjournal.com that mention about how easy that python can works with pipeline.
Here is the code quote from that article.
#! /usr/local/bin/python import sys sys.stdout.write(sys.stdin.read())
Well, I understand that served as a simple example to show how easy python can works with pipeline. But it is misleading because it doesn’t works well. People will think python sucks, because it doesn’t handle the pipeline properly. I find the code mined with two problems.
1. The shabang#!
Python scripts usually do not put the shabang directly point to the binaries like bash
Because python might be install at other location, therefore it is a correct practice to put in this way:
#! /usr/bin/env python
Which it tells the env to search for python binaries.
2. The script cannot run without feeding something from pipelines.
Okay lets makes the code above as toosimple.py and execute it as following lines
echo "hello python" | ./toosimple.py
Hey! this work perfectly.
But what if the user do not specified anything from the pipe?
This will cause the script do nothing but keep waiting for user input forever.
So, how should I detects whether is there any inputs from pipes?
Let us just look at a simple code that cater for pipelines as well as parameters.
#! /usr/bin/env python import sys def main(argv = sys.argv): # detects whether have pipe line parsing in if not sys.stdin.isatty(): for s in sys.stdin.readlines(): print "pipe: " + s, # param L = sys.argv[1:] if len(L)!=0: print "param: " + str(L) sys.exit(0) pass if __name__ == "__main__": try: main(sys.argv) except KeyboardInterrupt: pass
The important part is here
if not sys.stdin.isatty(): which it detects whether any inputs from pipelines.
So, lets try this simple.py now:
Nothing happen, expected.
echo "hello python" | ./simple.py
pipe: hello python
Its fine. Now lets try to put in parameters.
./simple.py hello world
param: ['hello', 'world']
It seems that param is in the form of list.
How about pass in the entire file?
./simple.py < myloveletter.txt
You can try it out yourself. Have fun :)