首页 > 解决方案 > Python3 运行带有多个预期引号的复杂 shell 命令

问题描述

当我从 bash 运行时:

# su -c "psql -d mapping -c \"INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');\"" postgres

它工作正常,但是当我从 python 尝试时:

subprocess.run("su -c \"psql -d mapping -c \"INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');\"\" postgres")

它失败了,我尝试了不同的引号,但都失败了。能否请你帮忙?

标签: python-3.xsubprocessquoting

解决方案


有两种解决方案,具体取决于您是否使用 Python 中的 shell。简单但低效的解决方案是传递字符串,shell=True基本上只是在它周围添加 Python 引用。

subprocess.run(r'''su -c "psql -d mapping -c \"INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');\"" postgres''', shell=True,
    # For good measure, you should check its status
    check=True)

更有效,也许实际上更易读,您可以从等式中删除 shell,并自己将命令拆分为字符串。

subprocess.run([
        'su', '-c',
        # The argument to "su -c" should be one string
        # Because we escaped the shell, the double quotes don't need escaping
        '''psql -d mapping -c "INSERT INTO mapping (ip,username) VALUES('1.2.3.4','test');"''',
        'postgres'],
    check=True)

请注意,shell=True第一个参数是如何传递给 shell 的字符串,而没有它,您将一个令牌列表直接传递给操作系统级别exec()或(在 Windows 上不太直接)CreateProcess()。另请注意,在第一个实例中,我如何使用r'...'字符串来避免 Python 干预字符串中的反斜杠。


推荐阅读