简体   繁体   English

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

[英]Pass Arguments to Start-Process with spaces

I would like to pass the powershell arguments to an process.我想将 powershell arguments 传递给一个进程。 The arguments may contain spaces. arguments 可能包含空格。

Powershell Code: Powershell 代码:

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

Run Command运行命令

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

No Output.没有 Output。


Running this command with static array works fine:使用 static 数组运行此命令工作正常:

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

Output Output

Hello World

What I needed todo to escape the arguments from the CLI args?我需要做什么才能从 CLI args 中转义 arguments?

See https://github.com/PowerShell/PowerShell/issues/5576 why I have to escape spaces请参阅https://github.com/PowerShell/PowerShell/issues/5576为什么我必须转义空格

The obvious answer is this, with $myargs being an array of strings.显而易见的答案是,$myargs 是一个字符串数组。 "echo Hello World" needs embedded double-quotes (or single-quotes) around it, which complicates things. “echo Hello World”需要在其周围嵌入双引号(或单引号),这使事情变得复杂。

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

Hello World

I would just do:我会这样做:

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

# sh.ps1 contains:
# wsl $args

Or the wsl bash for windows:或者 windows 的 wsl bash:

bash -c 'echo hello world'

I happened to have pwsh installed within wsl.我碰巧在 wsl 中安装了 pwsh。 Without the single-quotes, each word would be put on a new line.如果没有单引号,每个单词都会换行。

wsl pwsh -c "echo 'hello world'"

This works for me within another powershell, with yet another set of embedded quotes:这在另一个 powershell 中对我有用,还有另一组嵌入引号:

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

There's no good reason to use Start-Process in your case (see this GitHub docs issue for guidance on when Start-Process is and isn't appropriate).在您的情况下没有充分的理由使用Start-Process (请参阅此 GitHub 文档问题以获取有关Start-Process何时合适和不合适的指导)。

Instead, use direct execution , which is not only synchronous and runs in the same console window (for console applications such as wsl.exe ), but also allows you to directly capture or redirect output.相反,使用直接执行,它不仅是同步的并且在同一个控制台 window 中运行(对于wsl.exe控制台应用程序),还允许您直接捕获或重定向 output。

In doing so, you'll also be bypassing the longstanding Start-Process bug you mention ( GitHub issue #5576 ), because PowerShell double-quotes arguments passed to external programs as needed behind the scenes (namely if they contain spaces).这样做时,您还将绕过您提到的长期存在的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 

Note that you then also don't need to embed escaped " in your PowerShell CLI call:请注意,您也不需要在 PowerShell CLI 调用中嵌入转义的"

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

However, if your arguments truly needed embedded " , you'd run into another longstanding PowerShell bug that affects only direct invocation of external programs, necessitating manual escaping with \ - see this answer .但是,如果您的 arguments 确实需要嵌入" ,您会遇到另一个长期存在的 PowerShell 错误,该错误仅影响外部程序的直接调用,需要手动escaping 和\ - 请参阅此答案


If you do need to use Start-Process - eg if you want the process to run in a new (console) window - you'll have to provide embedded quoting around those $args elements that need it, along the following lines:如果您确实需要使用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