Python – What is the best way to escape bash commands in python?

What is the best way to escape bash commands in python?… here is a solution to the problem.

What is the best way to escape bash commands in python?

I have a function that receives a command as a string and runs it on an AWS container using an aws binary.

The command adds some extra symbols before and after the command requested by the user to run – I won’t explain why.

def run_command_on_aws_container(command: str, aws_info):
    full_command = f"bash -c 'echo -n \"|\"; {command}; echo -n \"|\"'"

subprocess.run(["aws", ..., "--command", full_command], ...)
    ...

command_to_run_on_aws_machine = 'python -c "for i in range(10): print(i)"'

run_command_on_aws_container(command_to_run_on_aws_machine, aws_info)

This works, but only if my command_to_run_on_aws_machine doesn’t contain single quotes. For example, if my command_to_run_on_aws_machine is something like this:

command_to_run_on_aws_machine = "python -c 'for i in range(10): print(i)'"

This is exactly the same command, but with single quotes instead of double quotes, the whole process crashes. Or at least it didn’t live up to your expectations.

Is there a way to get my run_command_on_aws_container function to work with two strings so that it runs as long as command arg is the correct bash command? Ideally, instead of just blindly converting all single quotes in a string to double quotes, but somehow if the command contains properly escaped quotes, it still works?

Note: All commands sent to run_command_on_aws_container as command args are hardcoded into the program. There is no security issue with executing arbitrary commands on a remote system. This is just for convenience, so code written outside of a function doesn’t need to worry about how to use strings correctly.

Solution

shlex.quote() is designed specifically for this:

full_command = "bash -c " + shlex.quote(f'echo -n "|"; {command}; echo -n "|"')

Related Problems and Solutions