使用撇号和python的子进程

时间:2017-07-03 08:20:01

标签: python linux python-3.x command-line subprocess

似乎我不能使用撇号,命令失败,没有任何信息错误。 我试图执行以下操作:

    secretLsCmd      = subprocess.Popen(('docker', 'secret', 'ls')     , stdout=subprocess.PIPE)
    oneWhitespaceCmd = subprocess.Popen(('tr', '-s','" "')             , stdout=subprocess.PIPE, stdin=secretLsCmd.stdout)
    onlySecretsCmd   = subprocess.check_output(('cut', "-d' '", '-f2') , stdin=oneWhitespaceCmd.stdout)

在普通的Linux终端中,它将执行以下命令:

docker secret ls | tr -s " " | cut -d' ' -f2

在CLI中运行此命令工作正常,但是一旦我把它放在python中它就不起作用了。管道中的2个第一个命令工作正常(我已经检查过),最后一个命令不起作用,退出时出现错误代码1 ...我几乎100%确定它是-d' ' ,但我该如何解决这个问题呢?任何想法?

1 个答案:

答案 0 :(得分:1)

这一行:

oneWhitespaceCmd = subprocess.Popen(('tr', '-s','" "'), ...)

实际上正在运行:

tr -s '" "'

所以你想在那里丢失额外的双引号:Python将引用它需要为shell引用的任何参数。

此命令:

onlySecretsCmd   = subprocess.check_output(('cut', "-d' '", '-f2'), ...)

等同于shell命令:

cut '-d'"'"' '"'"'' -f2

所以,你可能只想丢失空白处的引号:

onlySecretsCmd   = subprocess.check_output(('cut', "-d ", '-f2'), ...)

并将其留给Python以在必要时插入引号。这实际上会运行(应该等同于你想要的但不相同):

cut '-d ' -f2

我使用shlex.quote()来创建一个等同于你正在运行的命令的shell,虽然在实践中除非你告诉subprocess调用一个shell,它只会执行相当于命令bash执行的命令解析所有转义引号后。所以在内部逃避不会发生,但是也不需要区分参数的引号。