【问题标题】:How to get resulting subprocess command string如何获取生成的子进程命令字符串
【发布时间】:2012-08-26 12:34:23
【问题描述】:

我有 Python 子进程调用,它们被格式化为一系列参数(例如 subprocess.Popen(['ls','-l']) 而不是单个字符串(即 subprocess.Popen('ls -l'))。

当像我一样使用顺序参数时,有没有办法获取发送到 shell 的结果字符串(用于调试目的)?

一种简单的方法是我自己将所有参数连接在一起。但我怀疑这在所有情况下都与子进程所做的相同,因为使用序列的主要原因是'allow[s] the module to take care of any required escaping and quoting of arguments'

【问题讨论】:

  • subprocess 带有一个 list2cmdline 函数,可将参数列表转换为单个字符串,同时处理空格和引号。对你有用吗?
  • @Pierre:是的,这就是我想要的。我搜索了子流程文档页面(我链接到的那个),但不幸的是它没有提到它。如果您将您的建议放在答案中,我会将其标记为已接受。
  • 在 Unix/Linux 上,没有“发送到 shell 的结果字符串”之类的东西。参数是单独发送的。字符串仅在 Windows 上构建。
  • @interjay:有趣,不知道这个。

标签: python subprocess


【解决方案1】:

正如评论中提到的,subprocess 附带(文档页面中未记录)list2cmdline,它将参数列表转换为单个字符串。 根据源文档,list2cmdline 主要用于 Windows:

在 Windows 上:Popen 类使用 CreateProcess() 来执行子进程 程序,它对字符串进行操作。如果 args 是一个序列,它将是 使用 list2cmdline 方法转换为字符串。请注意 并非所有 MS Windows 应用程序都以相同的方式解释命令行 方式:list2cmdline 是为使用相同的应用程序设计的 规则作为 MS C 运行时。

不过,它在其他操作系统上非常有用。

编辑

如果您需要反向操作(ie,将命令行拆分为正确标记化的参数列表),您将需要使用 shlex.split 函数,如 @987654321 所示@。

>>> help(subprocess.list2cmdline)
Help on function list2cmdline in module subprocess:

list2cmdline(seq)
    Translate a sequence of arguments into a command line
    string, using the same rules as 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 3.

【讨论】:

  • 如果引用规则与 POSIX 完全不同,它如何“在其他操作系统上非常有用”?
【解决方案2】:

从 Python 3.8 开始,有一个 shlex.join() 函数:

>>> shlex.join(['ls', '-l'])
'ls -l'

【讨论】:

  • 如果你低于 Python 3.8 但 3.3 及更高版本,shlex.join() 只是' '.join(quote(arg) for arg in split_command)
猜你喜欢
  • 2020-01-20
  • 2011-11-18
  • 2016-12-29
  • 2018-11-05
  • 2011-03-08
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
相关资源
最近更新 更多