[Tutor] interacting with shell

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Thu, 18 Apr 2002 20:41:32 -0700 (PDT)


On Thu, 18 Apr 2002, Paul Tremblay wrote:

> I am wondering how (of if) you interact with shell commands in
> python. For example, in perl you can assign a variable to the
> output from a command line. (I am using linux.)
>
> $date = `date`
>
> The string between the backslashes gets passed to the shell.
>
> In python, I see you can use the command
>
> os.system('date')
>
> But can you assign this to a variable?


Hi Paul,

Not in the way we'd expect, since os.system() returns the "errorlevel" or
exit code of the command we execute.  However, there's a separate
process-spawning function called os.popen()  that's more like what you're
looking for:

###
myfile = os.popen('date')
###


What it returns back is a file-like-object, so you can either pass it off
to some other function, or just suck all the string out of it with a
read():

###
print os.popen('date').read()
###


os.popen() returns a file because it's possible that the shell command
could give us a huge huge string, so the file interface allows us to read
chunks in at a time to conserve memory if we wanted to.

There's more information on os.popen() here:

    http://www.python.org/doc/lib/os-newstreams.html




> Here is another example. I have written a small script in perl to
> backup my files. I use perl code to determine what type of backup
> I want to do, and store this value in the $backup variable. I
> can then pass this to the shell with a command like this.
>
> `find /bin -ctime -$backup \! -type d`
>
> Perl knows to change the variable $backup to the value stored in
> it and then passes it to the shell.
>
> I am hoping you can do this in python. If not, then I can see where I
> would be somewhat limited in python.

We can do it similarly, but it takes just a wee bit more to get Perl-style
"string interpolation" to fire off.  Here's a quick translation of the
above Perl code to Python:

###
>>> backup = "some backup file"
>>> command = "find /bin -ctime -%(backup)s \! -type d" % vars()
>>> command
'find /bin -ctime -some backup file \\! -type d'
###

Python names this concept "String Formatting", and there's more
information about it here:

    http://www.python.org/doc/current/lib/typesseq-strings.html

It's more explicit in that we're explicitely using the string formatting
operator '%'.  Python's string formatting is also a bit more flexible
because it takes in a dictionary ("hashtable") for its source of data, so
we could potentially feed it something other than our list of accessible
var()iables:

###
>>> command = "find /bin -ctime -%(backup)s \! -type d"
>>> command % {'backup' : 'on tape'}
'find /bin -ctime -on tape \\! -type d'
>>> command % {'backup' : 'time'}
'find /bin -ctime -time \\! -type d'
###



If you have more questions, please feel free to ask.  And welcome aboard!