Calling an application from inside a python script Take 1

Donn Cave donn at oz.net
Fri Jan 5 01:49:20 EST 2001


Quoth "Chris Watson" <scanner at jurai.net>:

| I *just* started getting into learning python.
| I am currently working on a menu'ing system to keep non admin people from
| goofing things up on some FreeBSD servers in a datacenter. I have very
| little BG in coding. My menu system has a section for allowing the admins
| to edit the various config files for different servers. For instance the
| first python script which I am doing prompts the user for a hostname of
| the server that apache is running on. It will save that hostname in the
| variable host.
|
| host = raw_input("Enter a hostname: ");
|
| Then I want to pass the $host variable to ssh. So it does something like
| this:
|
| ssh -l root $host vi /usr/local/etc/apache.conf
|
| Which will allow the tech to edit the web servers config file. But he
| wont need to know ssh, or or anything else. My long winded question is
| how do I get python to call an external application?
|
| If someone could point me in the right direction I would really
| appreciate it. Thanks for your time!

The easiest thing to write is

    import os
    ...
    os.system('ssh -l root %s vi /usr/local/etc/apache.conf' % host)


It's also about as dangerous as anything you can do in Python.  It
puts you completely at the mercy of whoever typed in that text at
the "Enter a hostname: " prompt.  Intentionally or not, a space
or a semi-colon etc. could yield very different results than you
intend.

Luckily, with Python 2.0 we're getting to the point where you can
do this in a safer way without writing all the fork & exec stuff
yourself.  The function, os.spawnv(), is apparently here for
compatibility with Windows!  but it seems to be what we need;
you can look at the os module to see how it works if you want.

    import os
    os.spawnv(os.P_WAIT, '/usr/local/bin/ssh', ('ssh', '-l', 'root',
        host, 'vi', '/usr/local/etc/apache.conf'))

That last argument is a tuple of the argument list to ssh, starting
with argv[0].  In the system() function, we would eventually invoke
the shell to parse the string into these arguments, and that's where
the unexpected metacharacters wreak their havoc.  By passing the
arguments directly to the ssh process, we avoid that.

Now, for this particular command, ssh, you might as well fold the
'vi' and the file together, because ssh is going to do that for
the remote shell to parse back out.  So don't think you can get
a sanitary calculated argument list through to the remote shell -
that can't happen.  Your example is OK, because the remote command
is constant.

	Donn Cave, donn at oz.net



More information about the Python-list mailing list