繁体   English   中英

将 Arguments 传递给带空格的 Start-Process

[英]Pass Arguments to Start-Process with spaces

我想将 powershell arguments 传递给一个进程。 arguments 可能包含空格。

Powershell 代码:

$proc = Start-Process -FilePath "wsl.exe" -ArgumentList $args -NoNewWindow -PassThru
$proc | Wait-Process

运行命令

powershell -noprofile -executionpolicy bypass -file sh.ps1 bash -c "`"echo Hello World`""

没有 Output。


使用 static 数组运行此命令工作正常:

$proc = Start-Process -FilePath "wsl.exe" -ArgumentList @("bash", "-c", "`"echo Hello World`"") -NoNewWindow -PassThru
$proc | Wait-Process

Output

Hello World

我需要做什么才能从 CLI args 中转义 arguments?

请参阅https://github.com/PowerShell/PowerShell/issues/5576为什么我必须转义空格

显而易见的答案是,$myargs 是一个字符串数组。 “echo Hello World”需要在其周围嵌入双引号(或单引号),这使事情变得复杂。

$myargs = "bash", "-c", "'echo Hello World'"
$proc = Start-Process -FilePath wsl.exe -ArgumentList $myargs -NoNewWindow -PassThru
$proc | Wait-Process

Hello World

我会这样做:

.\sh.ps1 bash -c 'echo hello world'

# sh.ps1 contains:
# wsl $args

或者 windows 的 wsl bash:

bash -c 'echo hello world'

我碰巧在 wsl 中安装了 pwsh。 如果没有单引号,每个单词都会换行。

wsl pwsh -c "echo 'hello world'"

这在另一个 powershell 中对我有用,还有另一组嵌入引号:

powershell -noprofile -executionpolicy bypass -file sh.ps1 bash -c "`"'echo Hello World'`""

在您的情况下没有充分的理由使用Start-Process (请参阅此 GitHub 文档问题以获取有关Start-Process何时合适和不合适的指导)。

相反,使用直接执行,它不仅是同步的并且在同一个控制台 window 中运行(对于wsl.exe控制台应用程序),还允许您直接捕获或重定向 output。

这样做时,您还将绕过您提到的长期存在的Start-Process错误( GitHub 问题 #5576 ),因为 PowerShell 双引号 arguments 在幕后根据需要传递给外部程序(即如果它们包含空格)。

$exe, $exeArgs = $args   # split argument array into exe and pass-thru args
wsl.exe -e $exe $exeArgs # execute synchronously, via wsl -e 

请注意,您也不需要在 PowerShell CLI 调用中嵌入转义的"

powershell -noprofile -executionpolicy bypass -file sh.ps1 bash -c "echo Hello World"

但是,如果您的 arguments 确实需要嵌入" ,您会遇到另一个长期存在的 PowerShell 错误,该错误仅影响外部程序的直接调用,需要手动escaping 和\ - 请参阅此答案


如果您确实需要使用Start-Process - 例如,如果您希望进程在新的(控制台)window中运行 - 您必须在需要它的那些$args元素周围提供嵌入式引号,如下所示:

$quotedArgs = foreach ($arg in $args) {
  if ($arg -notmatch '[ "]') { $arg }
  else { # must double-quote
    '"{0}"' -f ($arg -replace '"', '\"' -replace '\\$', '\\')
  }
}

$proc = Start-Process -FilePath "wsl.exe" -ArgumentList $quotedArgs -PassThru
$proc | Wait-Process

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM