os.popen output different from native shell output

Discussion in 'Python' started by nickname, Aug 25, 2009.

  1. nickname

    nickname Guest

    Hi all,
    I am a relative newbie to python, I am using os.popen to run an
    ls command. The output that I get using the read() function is
    different in look and feel from when I run the ls command natively
    from the shell (not via python). I display the ouput via python by
    using the print function on the variable that accepts the os.popen
    ().read() function.

    For example:

    output from native shell (as seen on the bash shell)

    file1 file2 dir1(highlighted in blue color)
    file3longnamewhichwillcausenextfiletoappearonnextline

    file 4

    output from python (as seen on the bash shell)

    file1
    file2
    dir1 (no blue color)
    file3longnamewhichwillcausenextfiletoappearonnextline
    file4

    Is there an easy way to "mirror" the output. When python displays the
    output, how can it tell the bash shell that some of the entries are
    directories and they should appear blue on the bash shell, and that
    everything should not be appearing on 1 column only.

    Thanks for any pointers.
    nickname, Aug 25, 2009
    #1
    1. Advertising

  2. nickname

    Chris Rebert Guest

    On Tue, Aug 25, 2009 at 1:36 AM, nickname<> wrote:
    > Hi all,
    >       I am a relative newbie to python, I am using os.popen to run an
    > ls command. The output that I get using the read() function is
    > different in look and feel from when I run the ls command natively
    > from the shell (not via python). I display the ouput via python by
    > using the print function on the variable that accepts the os.popen
    > ().read() function.
    >
    > For example:
    >
    > output from native shell (as seen on the bash shell)
    >
    > file1 file2 dir1(highlighted in blue color)
    > file3longnamewhichwillcausenextfiletoappearonnextline
    >
    > file 4
    >
    > output from python (as seen on the bash shell)
    >
    > file1
    > file2
    > dir1 (no blue color)
    > file3longnamewhichwillcausenextfiletoappearonnextline
    > file4
    >
    > Is there an easy way to "mirror" the output. When python displays the
    > output, how can it tell the bash shell that some of the entries are
    > directories and they should appear blue on the bash shell, and that
    > everything should not be appearing on 1 column only.


    I would assume the difference is caused by `ls` changing behavior (for
    example, enabling/disabling colorization) based on whether its output
    is going to a terminal or a pipe.

    Is there a reason you can't use os.listdir() instead of running ls?:
    http://docs.python.org/library/os.html#os.listdir

    For the colorization, google for "ANSI color escape sequences"

    Cheers,
    Chris
    --
    http://blog.rebertia.com
    Chris Rebert, Aug 25, 2009
    #2
    1. Advertising

  3. hi,

    you get the popen output like this:

    user@unixhost> ls | cat


    nickname schrieb:
    > Hi all,
    > I am a relative newbie to python, I am using os.popen to run an
    > ls command. The output that I get using the read() function is
    > different in look and feel from when I run the ls command natively
    > from the shell (not via python). I display the ouput via python by
    > using the print function on the variable that accepts the os.popen
    > ().read() function.

    ....

    Thomas


    --
    Thomas Guettler, http://www.thomas-guettler.de/
    E-Mail: guettli (*) thomas-guettler + de
    Thomas Guettler, Aug 25, 2009
    #3
  4. nickname

    Nobody Guest

    On Tue, 25 Aug 2009 01:36:08 -0700, nickname wrote:

    > I am a relative newbie to python, I am using os.popen to run an
    > ls command. The output that I get using the read() function is
    > different in look and feel from when I run the ls command natively
    > from the shell (not via python).


    As others have pointed out, the default behaviour of ls is different if
    its output is a terminal.

    > Is there an easy way to "mirror" the output. When python displays the
    > output, how can it tell the bash shell that some of the entries are
    > directories and they should appear blue on the bash shell, and that
    > everything should not be appearing on 1 column only.


    You can get the terminal-style behaviour even when using a pipe with:

    ls -x --color

    But why are you reading this information into Python then writing it
    back out to the terminal?

    If you're planning on processing the output within Python, both the
    multi-column format and the escape sequences used for colour will make
    such processing awkward.

    If you want to enumerate the contents of a directory within Python, use
    os.listdir().

    If you want to generate coloured output, use the curses module, e.g.:

    #!/usr/bin/env python

    import sys
    import curses

    curses.setupterm()
    setaf = curses.tigetstr('setaf') or ""
    setab = curses.tigetstr('setab') or ""
    origp = curses.tigetstr('op') or ""

    def fg(c):
    sys.stdout.write(curses.tparm(setaf, c))

    def bg(c):
    sys.stdout.write(curses.tparm(setab, c))

    def orig():
    sys.stdout.write(origp)

    # example
    bg(curses.COLOR_BLUE)
    fg(curses.COLOR_YELLOW)
    print "hello, world"
    orig()
    Nobody, Aug 25, 2009
    #4
  5. nickname

    nickname Guest

    On Aug 25, 6:16 am, Nobody <> wrote:
    > On Tue, 25 Aug 2009 01:36:08 -0700, nickname wrote:
    > >        I am a relative newbie to python, I am using os.popen to run an
    > > ls command. The output that I get using the read() function is
    > > different in look and feel from when I run the ls command natively
    > > from the shell (not via python).

    >
    > As others have pointed out, the default behaviour of ls is different if
    > its output is a terminal.
    >
    > > Is there an easy way to "mirror" the output. When python displays the
    > > output, how can it tell the bash shell that some of the entries are
    > > directories and they should appear blue on the bash shell, and that
    > > everything should not be appearing on 1 column only.

    >
    > You can get the terminal-style behaviour even when using a pipe with:
    >
    >         ls -x --color
    >
    > But why are you reading this information into Python then writing it
    > back out to the terminal?
    >
    > If you're planning on processing the output within Python, both the
    > multi-column format and the escape sequences used for colour will make
    > such processing awkward.
    >
    > If you want to enumerate the contents of a directory within Python, use
    > os.listdir().
    >
    > If you want to generate coloured output, use the curses module, e.g.:
    >
    > #!/usr/bin/env python
    >
    > import sys
    > import curses
    >
    > curses.setupterm()
    > setaf = curses.tigetstr('setaf') or ""
    > setab = curses.tigetstr('setab') or ""
    > origp = curses.tigetstr('op') or ""
    >
    > def fg(c):
    >     sys.stdout.write(curses.tparm(setaf, c))
    >
    > def bg(c):
    >     sys.stdout.write(curses.tparm(setab, c))
    >
    > def orig():
    >     sys.stdout.write(origp)
    >
    > # example
    > bg(curses.COLOR_BLUE)
    > fg(curses.COLOR_YELLOW)
    > print "hello, world"
    > orig()


    wow guys! thanks for all the great leads! this is awesome!

    The reason why I want to do this is because I am going to do a little
    project. I will write a python script called ls which will log the
    time and username and then will show the actual ls output. I want this
    to be transparent and so want to throw the ls output (via python)
    exactly as it will be in native shell execution.

    I know there's history files I can look up, but I just am exploring my
    own intermediate-logging-layer the functionality for which is executed
    right before the actual command is executed.

    Thanks,
    -A
    nickname, Aug 25, 2009
    #5
  6. In one of the first chapters of "Advanced programming in the unix
    environment (second edition)" there is explained how a unix shell works.

    You could write you own shell using python. This way the python
    interpreter gets stared only once, and not for every call to "ls".



    Have fun,
    Thomas

    nickname schrieb:
    > wow guys! thanks for all the great leads! this is awesome!
    >
    > The reason why I want to do this is because I am going to do a little
    > project. I will write a python script called ls which will log the
    > time and username and then will show the actual ls output. I want this
    > to be transparent and so want to throw the ls output (via python)
    > exactly as it will be in native shell execution.
    Thomas Guettler, Aug 25, 2009
    #6
  7. nickname

    nickname Guest

    On Aug 25, 11:57 am, Thomas Guettler <>
    wrote:
    > In one of the first chapters of "Advanced programming in the unix
    > environment (second edition)" there is explained how a unix shell works.
    >
    > You could write you own shell using python. This way the python
    > interpreter gets stared only once, and not for every call to "ls".
    >
    > Have fun,
    >   Thomas
    >
    > nickname schrieb:
    >
    > > wow guys! thanks for all the great leads! this is awesome!

    >
    > > The reason why I want to do this is because I am going to do a little
    > > project. I will write a python script called ls which will log the
    > > time and username and then will show the actual ls output. I want this
    > > to be transparent and so want to throw the ls output (via python)
    > > exactly as it will be in native shell execution.

    >
    >


    very good point, I will look it up :)
    nickname, Aug 25, 2009
    #7
  8. nickname

    Nobody Guest

    On Tue, 25 Aug 2009 11:42:31 -0700, nickname wrote:

    > The reason why I want to do this is because I am going to do a little
    > project. I will write a python script called ls which will log the
    > time and username and then will show the actual ls output. I want this
    > to be transparent and so want to throw the ls output (via python)
    > exactly as it will be in native shell execution.


    If your script doesn't need the "ls" output for its own purposes, just run
    "ls" with its output to the terminal, rather than into a pipe. I.e. don't
    use os.popen(), but use os.spawnvp(), os.execvp() or subprocess.call().

    If running "ls" is the very last thing which your script does, use
    os.execvp(). This causes the program to be executed in the existing
    process, rather than spawning a child process and waiting for it to exit.

    Because they replace the existing program (the Python interpreter), the
    various os.exec* functions don't return (unless there's an error). If you
    need to perform any action after the command completes (e.g. log the
    execution time), you need to use one of the other functions instead.
    Nobody, Aug 26, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nick Craig-Wood

    Avoiding shell metacharacters in os.popen

    Nick Craig-Wood, Sep 29, 2004, in forum: Python
    Replies:
    10
    Views:
    586
    David Fraser
    Oct 1, 2004
  2. Tom Brown
    Replies:
    0
    Views:
    444
    Tom Brown
    Sep 22, 2005
  3. jelle
    Replies:
    4
    Views:
    331
    Serge Orlov
    Apr 19, 2006
  4. Replies:
    3
    Views:
    351
  5. File.popen/IO.popen

    , May 20, 2006, in forum: Ruby
    Replies:
    1
    Views:
    210
    Robert Klemme
    May 20, 2006
Loading...

Share This Page