Live Chat!

python: handle string from pipelines and list of param

* * * * * 1 votos

November 13th, 2007 mysurface Posted in Developer, python | Hits: 18912 |

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

#! /usr/local/bin/python

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?

./toosimple.py

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:

./simple.py

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 :)

3 Responses to “python: handle string from pipelines and list of param”

  1. Thanks that was extremely helpful. Thanks to you I have a new idea I am working on.

    Thanks!-Patrick

  2. echo “hello python” | ./simple.py
    is not worked
    Traceback (most recent call last):
    File “D:\python\pipe\simple.py”, line 3, in
    sys.stdout.write(sys.stdin.read())
    IOError: [Errno 9] Bad file descriptor

    echo “hello python” | ./toosimple.py
    is not worked
    D:\python\pipe>echo “wefwef” | toosimply.py
    Traceback (most recent call last):
    File “D:\python\pipe\toosimply.py”, line 18, in
    main(sys.argv)
    File “D:\python\pipe\toosimply.py”, line 7, in main
    for s in sys.stdin.readlines():
    IOError: [Errno 9] Bad file descriptor

    M$ windows

  3. @qman, My implementation will only works on Linux.

Leave a Reply