在PowerShell中运行命令行

SSE*_*SED 1 syntax powershell quoting

我知道有很多与此相关的帖子,但对我没有任何帮助。

我正在尝试在PowerShell中运行以下命令行:

C:/Program Files (x86)/ClamWin/bin/clamd.exe --install
Run Code Online (Sandbox Code Playgroud)

我在PowerShell中有这个:

&"C:/Program Files (x86)/ClamWin/bin/clamd.exe --install"
Run Code Online (Sandbox Code Playgroud)

但这只是执行clamd.exe,忽略--install参数

如何获得完整的命令行来运行?

mkl*_*nt0 5

Josef Z对这个问题评论提供了解决方案:

& "C:/Program Files (x86)/ClamWin/bin/clamd.exe" --install # double-quoted exe path
Run Code Online (Sandbox Code Playgroud)

或者,假定可执行路径是文字(不包含变量引用或子表达式):

& 'C:/Program Files (x86)/ClamWin/bin/clamd.exe' --install # single-quoted exe path
Run Code Online (Sandbox Code Playgroud)

至于您自己的解决方案尝试失败的原因:呼叫操作员&只希望将命令名称/路径作为参数,而不希望使用完整的命令行
Invoke-Expression接受整个命令行,但这会使事情变得更加复杂,并且可能带来安全风险

至于为什么这是解决方案:

  • 需要引用按理说:你需要告诉PowerShell的这C:/Program Files (x86)/ClamWin/bin/clamd.exe是一个单一的令牌(路径),尽管包含嵌入空格

  • &之所以需要所谓的调用运算符,是因为 PowerShell具有两种基本的解析模式

    • arguments mode,其工作方式类似于传统的shell,其中第一个标记是命令名称,后继标记表示参数,仅当它们包含外壳元字符(对于PowerShell具有特殊含义的字符,例如用于分隔标记的空格)时,才需要引号);
      这就是为什么--install 不需要,但可以将其引起来(PowerShell会在将参数传递给目标可执行文件之前简单地为您删除引号。)

    • 表达式模式类似于编程语言中的表达式

PowerShell根据语句的第一个令牌决定要应用哪种解析模式:

如果第一个标记是带引号的字符串(由于可执行路径中包含空格,在此需要使用引号的字符串)变量引用(例如$var ...),默认情况下,PowerShell以表达式模式进行解析
带引号的字符串或变量引用作为表达式将只输出字符串/变量值。

但是,鉴于我们要执行其路径存储在带引号的字符串中的可执行文件,我们需要强制使用参数模式,这是&操作员要确保的


通常,重要的是要了解,PowerShell在调用目标可执行文件之前会对命令行执行非平凡的预处理,因此,PowerShell代码中的命令行外观通常不是目标可执行文件直接看到的内容。

  • 如果您在命令行上引用PowerShell 变量,并且该变量包含嵌入式空格,那么PowerShell会将变量的值隐式括在双引号中,然后再传递给它-对此链接问题的答案对此进行了讨论。

  • PowerShell的元字符不同于,cmd.exe并且数量更多(值得注意的是,,在PowerShell(数组构造函数)中具有特殊的含义,但是没有cmd.exe-请参阅此答案)。

  • 为了简化现有cmd.exe基于命令行的重用,PowerShell v3引入了特殊的停止解析符号--%符号关闭了PowerShell对命令行其余部分的常规解析,并且仅插值了cmd.exe-style环境变量引用(例如%USERNAME%)。