[英]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.