Embed bash in python
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, stderrclass 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, 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.
Is
import osos.system ("bash -c 'echo $0'")
going to do it for you?
EDIT: regarding readability
Yes, of course, you can have it more readable
import osscript = """echo $0ls -lecho 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 osdef 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)