【问题标题】:In Python, with subprocess.Popen, is it possible to pass literal quotes to the command to be run, when Popen's command line parameter is in list form?在 Python 中,使用 subprocess.Popen,当 Popen 的命令行参数为列表形式时,是否可以将文字引号传递给要运行的命令?
【发布时间】:2022-08-13 21:43:38
【问题描述】:

在 Python 中,使用 subprocess.Popen,当命令及其参数采用列表形式时,是否可以将文字引号作为参数传递?

我会进一步解释我的意思。某些命令在其参数中需要文字引号,例如\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" --profile-directory=\"Profile 1\"

为简单起见,我将使用 calc.exe,因为它在路径中。

import time
import subprocess

proc=subprocess.Popen(\"calc.exe\"+\" \"+\'--profile-directory=\"Profile 3\"\')
proc2=subprocess.Popen([\"calc.exe\",\'--profile-directory=\"Profile 4\"\'])

time.sleep(3)

proc.wait()
proc2.wait()

现在查看在任务管理器中或通过 wmic 可见的命令行中的差异。

C:\\Users\\User>wmic 进程 where caption=\"calc.exe\" 获取命令行 | findstr 计算
    c:\\windows\\system32\\calc.exe --profile-directory=\"配置文件 3\"
    c:\\windows\\system32\\calc.exe \"--profile-directory=\\\"配置文件4\\\"\"
    
    C:\\用户\\用户>

添加

一个建议假设--profile-directory=\"Profile 1\"--profile-directory \"Profile 1\" 相同,即假设您可以将= 替换为空格并且chrome 的工作方式相同。但事实并非如此。所以写subprocess.Popen([\"C:\\...\\chrome.exe\", \"--profile-directory\", \"Profile 3\"]) 确实会产生\"C:\\....\\chrome.exe\" --profile-directory \"Profile 1\" 但这不会起作用.. 它会导致chrome 要么根本不打开,要么打开一个提供配置文件供点击的浏览器窗口。等号是必须的。

另一个建议确实

subprocess.Popen(
    \" \".join(
        [
            \"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",
            \'--profile-directory=\"Person 1\"\',
        ]
    )

那不是将列表传递给 Popen,而是将列表传递给 join,而 join 是将其转换为字符串。

另一个建议是

subprocess.Popen(\'C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe --profile-directory=\"Profile 3\"\')

那是使用字符串。但是正如您从我的问题中看到的那样,我使用字符串对其进行了管理。我问的是使用列表。

另一个建议建议\"--profile-directory=\'Profile 1\'\"

如果我使用 --profile-directory=\"Profile 1\" 运行 chrome,我会得到一个我有时使用的特定配置文件。但是,如果使用 \"--profile-directory=\'Profile 1\'\" 运行 chrome,那么它不会加载该配置文件。它加载一个空白配置文件。并且去 chrome://version 显示 \"\'profile 1\'\" 而不是 \"profile 1\" 这就像一个不同的配置文件,就像你可能已经说过 chrome.exe --profile-directory=\"profile A\"

另一个建议建议

subprocess.Popen(
    [
        \"C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",
        \"--profile-directory=Profile 1\",
    ]

这很有趣,因为它确实\"C:\\...chrome.exe\" \"--profile-directory=Profile 1\"

它确实使用指定的配置文件加载 chrome。虽然它不会尝试传递文字引号!

我的问题询问何时传递文字引号。就好像它假设它是一个 linux shell 并在它之前插入一个反斜杠,这在 linux 中将确保引号使其通过 shell 并进入正在运行的程序。虽然我不确定它甚至会转到 linux 上的 linux shell。例如在 Windows 上,如果我在其中粘贴一个 cmd 转义字符,例如 ^ 所以 \"--pro^file-directory=Profile 1\" 那么 ^ 只是按字面意思传递。所以 cmd shell 不会干预。

    标签: python popen


    【解决方案1】:

    应该做的伎俩(如果没有,可能想将shell=True 传递给 Popen):

    subprocess.Popen(["C:\Program Files (x86)\Google\Chrome\Application\chrome.exe", "--profile-directory", "Profile 3"]);
    

    这是可能的,因为--some-flag="some value"--some-flag "some value" 相同

    ChRomE 解决方案(工作,天哪):

    import subprocess
    
    subprocess.Popen(
        [
            "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
            "--profile-directory=Profile 1",
        ]
    )
    

    【讨论】:

    • 你写“这是可能的,因为 --some-flag="some value" 与 --some-flag "some value"" <-- 不是 chrome 它没有! Chrome 需要 = 那里。用空格替换它是行不通的。然后,Chrome 要么根本不启动,要么启动它但不转到配置文件,只显示配置文件列表,然后单击所需的配置文件。
    • 这是在 99% 的情况下传递带有值的标志的常见替代语法,也许这是一个例外。 subprocess.Popen('C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe --profile-directory="Profile 3"') 应该可以工作
    • 好吧,请参阅问题、标题、第一段,并且自始至终,我都展示了非列表变体的工作,所以我知道这是有效的,但我特别询问了命令及其参数何时以列表形式出现
    • 是的,下载了 chrome,有趣的东西,我猜他们编写了自己的 cli 参数解析器,它像狗一样工作***,但我得到了一个解决方案,更新了答案。
    • 好吧,我可以看到你没有将列表传递给 Popen。你只是拿了一个列表并使用 join 将其转换为字符串!可以使用字符串开头。虽然我想知道将列表传递给 POpen。看起来它无法完成..所以我想知道..为什么不能..为什么 Popen 会那样做..在列表的情况下,(将列表传递给 Popen),它会起作用就像传递给 linux shell 一样。'cos linux 会去掉引号,因此需要用 `\` 转义它们(续)
    猜你喜欢
    • 2013-02-02
    • 2014-08-30
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    相关资源
    最近更新 更多