如何确定传递给命令行的字符串子进程?

How to determine what string subprocess is passing to the commandline?

在 Windows 上,您通过传递字符串参数列表进行子进程调用,然后将其重新格式化为单个字符串以调用相关命令。它通过文档 here.

中概述的一系列规则来执行此操作

On Windows, an args sequence is converted to a string that can be parsed using the following rules (which correspond to the rules used by the MS C runtime):

  1. Arguments are delimited by white space, which is either a space or a tab.
  2. A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
  3. A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.
  4. Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
  5. If backslashes immediately precede a double quotation mark, every pair of backslashes is interpreted as a literal backslash. If the number of backslashes is odd, the last backslash escapes the next double quotation mark as described in rule

然而在实践中这很难做到正确,因为不清楚字符串是如何被解释的。在弄清楚如何正确格式化命令时可能会反复试验。

有没有一种方法可以确定子进程将制定什么字符串?这样我就可以检查它并确保它被正确地制定并记录它比只记录命令的列表形式更好。

我深入研究了实际的子流程模块,实际上在那里找到了答案。有一个名为 list2cmdline 的函数,它用于仅获取传递给 Popen 的列表并将其转换为单个命令行参数字符串。只需用列表调用它即可获得我需要的结果:

import subprocess

name = "Monty Python's Flying Circus"
path = r"C:\path\to\files"
subprocess.list2cmdline(["file.py", name, path])
# 'file.py "Monty Python\'s Flying Circus" C:\path\to\files'