Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save malcolmgreaves/bb4312c6bb65a3e1080c61437fbddcbc to your computer and use it in GitHub Desktop.
Save malcolmgreaves/bb4312c6bb65a3e1080c61437fbddcbc to your computer and use it in GitHub Desktop.
Function to execute an arbitrary-length BASH script from Python; always returns a CompletedProcess object.
# Uses `strip_margin` defined here:
# https://gist.github.com/malcolmgreaves/7c9ec3407a02a3eb6d4b898bc16dc902
import subprocess
def exec_bash_script(
script_contents: str, *, prepend_bash_shebang_if_needed: bool = True
) -> subprocess.CompletedProcess:
script_contents = script_contents.strip()
if len(script_contents) == 0:
raise ValueError("Cannot supply empty string for script execution!")
if not script_contents.startswith("#!/"):
if prepend_bash_shebang_if_needed:
script_contents = "#!/usr/bin/env bash\n" + script_contents
else:
try:
x = script_contents[0 : script_contents.index("\n")]
except IndexError:
x = script_contents
raise ValueError(f"No shebang line found in script contents:\n{x}")
script_contents = strip_margin(script_contents)
with NamedTemporaryFile() as tfi:
# write docker ECR login + pull script
tfi.close()
with open(tfi.name, "wt") as wt:
wt.write(script_contents)
chmod_cmd = ["chmod", "+x", tfi.name]
exit_code = subprocess.check_call(chmod_cmd)
if exit_code != 0:
raise ValueError("Could not make script executable!")
completed = subprocess.run(tfi.name, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
completed.args = [script_contents]
return completed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment