Идеальный способ сделать это:
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')
Вы также можете добавить хороший __str__
метод к ScriptException
(он вам обязательно понадобится для отладки ваших скриптов) - но я оставлю это читателю.
Если вы не используете stdout=subprocess.PIPE
и т. Д., Сценарий будет прикреплен непосредственно к консоли. Это действительно удобно, если у вас есть, например, запрос пароля от ssh. Поэтому вы можете захотеть добавить флаги, чтобы контролировать, хотите ли вы захватить stdout, stderr и stdin.