如何在Python中最好地退出bash命令?

3

我有一个函数,它接收一个命令字符串,并使用aws二进制文件在AWS容器上运行该命令。

该命令在用户请求运行之前会添加一些额外符号,我不会详细解释原因。

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)

这个方法是有效的,但仅当我的command_to_run_on_aws_machine中没有单引号。例如,如果我的command_to_run_on_aws_machine是这样的:

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

使用单引号而不是双引号的完全相同的命令会导致整个程序崩溃。或者至少它不会按照您期望的方式运行。

有没有一种方法可以使我的run_command_on_aws_container函数与两种字符串配合使用,只要command参数是一个正确的bash命令,它就会运行?理想情况下,不仅将所有单引号盲目转换为双引号,而且在命令包含适当转义引号的情况下,它仍然可以正常工作?

注意:所有作为command参数发送到run_command_on_aws_container的命令都是硬编码到程序中的。在远程系统上执行任意命令的安全问题不存在。这仅仅是为了方便,以便在函数外部编写的代码无需担心如何正确使用字符串。


1
使用 shlex.quote() - Barmar
出于好奇,您可以确认|字符的存在是否意味着 shell 管道吗?看起来似乎不是,但由于所有特殊转义字符都很难一眼看清。很高兴了解 shlex.quote :-) - JL Peyret
1
@JLPeyret 在这个例子中并没有使用管道,但在我的实际代码中是有的,这让事情更加有趣 :) - John
1个回答

3

shlex.quote()专门为此而设计:

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

我几分钟前遇到了shlex.quote,在创建这篇文章之前尝试了几种不同的方法,但都没有成功。你的例子让它几乎立刻就能工作了。谢谢! - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接