python subprocess 在引号前发送反斜杠
我有一个字符串,这个字符串是一个命令,应该在命令行中执行。
cmdToExecute = "TRAPTOOL -a STRING "ABC" -o STRING 'XYZ'"
我把这个字符串看作是一个完整的命令,应该从命令提示符中触发。如果仔细看看这个字符串cmdToExecute,你会发现选项o的值XYZ是用单引号括起来的。这是有原因的,如果不使用单引号,我的工具TRAPTOOL就无法处理这个命令。
我使用subprocess.Popen来执行整个命令。在执行命令之前,我会先打印出内容。
print "Cmd to be exectued: %r" % cmdToExecute
myProcess = subprocess.Popen(cmdToExecute, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
(stdOut, stdErr) = myProcess.communicate()
上面命令的输出是,
要执行的命令:TRAPTOOL -a STRING "ABC" -o \'XYZ\'。
你可以看到,输出中自动添加了一个反斜杠。实际上,这个反斜杠在字符串中并不存在,我用正则表达式测试过。但是,当我在我的机器上运行脚本时,TRAPTOOL在接收服务器上截断了字符串XYZ的部分。我手动复制粘贴了打印输出并尝试发送,结果在接收服务器上也出现了同样的错误。不过,当我去掉反斜杠时,命令就能完整发送,没有被截断。
- 有人能说说为什么会这样吗?
- 有没有办法查看subprocess.Popen实际执行的命令是什么?
- 有没有其他方法可以执行我的命令,而不是用subprocess.Popen,这样可能解决这个问题?
2 个回答
4
你问的是字符串的 repr
表示,而不是 str
表示。简单来说,你在 Python 交互式解释器里输入什么,才能得到一样的输出?这就是 %r
显示的内容。如果把它改成 %s
,你就能看到实际存储的值是怎样的:
print "Cmd to be exectued: %s" % cmdToExecute
4
试试用 shlex
来分割你的命令字符串:
>>> import shlex
>>> argv = shlex.split("TRAPTOOL -a STRING \"ABC\" -o STRING 'XYZ'")
>>> myProcess = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
>>> (stdOut, stdErr) = myProcess.communicate()
在 Popen
的构造函数中,第一个参数可以是你要执行的命令的参数列表,也可以是一个字符串。不过,使用参数列表可能更简单,因为涉及到很多引号。(可以参考 Python的子进程文档。)
如果你想看到正在执行的命令,可以试试这样做:
>>> argv = shlex.split("bash -x -c 'TRAPTOOL -a STRING \"ABC\" -o STRING \'XYZ\''")
这样做会让 bash
通过 -x
选项把命令打印到终端上。