python subprocess 在引号前发送反斜杠

4 投票
2 回答
1599 浏览
提问于 2025-04-18 00:44

我有一个字符串,这个字符串是一个命令,应该在命令行中执行。

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的部分。我手动复制粘贴了打印输出并尝试发送,结果在接收服务器上也出现了同样的错误。不过,当我去掉反斜杠时,命令就能完整发送,没有被截断。

  1. 有人能说说为什么会这样吗?
  2. 有没有办法查看subprocess.Popen实际执行的命令是什么?
  3. 有没有其他方法可以执行我的命令,而不是用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 选项把命令打印到终端上。

撰写回答