views:

296

answers:

5

Hi,

I am writting a python script and I am running out of time. I need to so some things that I know pretty well in bash, so I just wonder how can I embed some bash lines into a python script.

Thanks

A: 

Assuming the command is supported by the host system:

import os
os.system('command')
waffleman
A: 

Is

import os
os.system ("bash -c 'echo $0'")

going to do it for you?

EDIT: regarding readability

Yes, of course, you can have it more readable

import os
script = """
echo $0
ls -l
echo done
"""
os.system("bash -c '%s'" % script)

EDIT2: regarding macros, no python does not go so far as far as i know, but between

import os
def sh(script):
    os.system("bash -c '%s'" % script)

sh("echo $0")
sh("ls -l")
sh("echo done")

and previous example, you basically get what you want (but you have to allow for a bit of dialectical limitations)

Unreason
great!and, is it some shortcut or workaround for making it easier or more eye-appealing?
Werner
I mean, can i define some macro in python like;(#define sh os.system(" ....."), so in the code i just write, sh ps -ef ?
Werner
+2  A: 

if you want to call system commands, use the subprocess module. Note that I gave you a link to a google search. The first result is the documentation so, read it. The other links are also useful for you.

ghostdog74
-1 for using tinyurl to link to a google search rather than pointing to a directly useful resource.
Donal Fellows
+1 for the resource at the end being really useful, and the right answer to this question. Here's a direct link: http://docs.python.org/library/subprocess.html
Personman
@Donal, the reason i do that is because there are other useful sites that show subprocess examples as well. furthermore, the first search result is the documentation itself. that should not be problem at all.
ghostdog74
@ghostdog74: Nonetheless, you should give direct links anyway. Show a little more bottle; choose!
Donal Fellows
A: 

Theres also the commands module to give more control over the output: http://docs.python.org/library/commands.html

gander
@gander I think you got down voted because Commands is being deprecated out of Python.
David
Oh! Not a good start. Surely its still going to be valid for people stuck on older versions though?
gander
+3  A: 

The ideal way to do it:

def run_script(script, stdin=None):
    """Returns (stdout, stderr), raises error on non-zero return code"""
    import subprocess
    # Note: by using a list here (['bash', ...]) you avoid quoting issues, as the 
    # arguments are passed in exactly this order (spaces, quotes, and newlines won't
    # cause problems):
    proc = subprocess.Popen(['bash', '-c', script],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        stdin=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    if proc.returncode:
        raise ScriptException(proc.returncode, stdout, stderr, script)
    return stdout, stderr

class ScriptException(Exception):
    def __init__(self, returncode, stdout, stderr, script):
        self.returncode = returncode
        self.stdout = stdout
        self.stderr = stderr
        Exception.__init__('Error in script')

You might also add a nice __str__ method to ScriptException (you are sure to need it to debug your scripts) -- but I leave that to the reader.

If you don't use stdout=subprocess.PIPE etc then the script will be attached directly to the console. This is really handy if you have, for instance, a password prompt from ssh. So you might want to add flags to control whether you want to capture stdout, stderr, and stdin.

Ian Bicking
wow very interesting!
Werner
I'm pretty sure that's 10x cooler than what he was looking for.
bukzor