Python3运行带有多个预期引号的复杂shell命令

时间:2018-09-05 19:24:43

标签: python-3.x subprocess quoting

当我从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")

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

1 个答案:

答案 0 :(得分:1)

有两种解决方案,具体取决于您是否使用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)

您可以从等式中删除外壳程序,然后将命令自己拆分为字符串,从而更有效地(也许实际上更易读)。

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的字符串,而没有它,则将令牌列表直接传递给OS级别的exec()或(有点不那么直接)在Windows上)CreateProcess()。还请注意,在第一个实例中,我是如何使用r'...'字符串来避免Python插入字符串中的反斜杠的。