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 "|"')