os.popen output different from native shell output

N

nickname

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.
 
C

Chris Rebert

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
 
T

Thomas Guettler

hi,

you get the popen output like this:

user@unixhost> ls | cat

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
 
N

Nobody

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()
 
N

nickname

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


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
 
T

Thomas Guettler

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
 
N

nickname

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

very good point, I will look it up :)
 
N

Nobody

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top