拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 powershell管道运算子

powershell管道运算子

白鹭 - 2022-01-23 2104 0 0

我执行了以下三个 powershell 命令。前两个命令没有回传结果,第三个命令回传结果。这三个命令之间的主要区别在于等待自变量和括号的使用。

PS C:\Users> Start-Process -FilePath 'msiexec' -ArgumentList '/IC:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet' -PassThru | Foreach-Object -Process { $_.exitcode }

PS C:\Users> Start-Process -FilePath 'msiexec' -ArgumentList '/IC:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet' -PassThru -wait | Foreach-Object -Process { $_.exitcode }

PS C:\Users> (启动行程 -FilePath 'msiexec' -ArgumentList '/IC:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet' -PassThru -Wait)| Foreach-Object -Process { $_.exitcode }

1619

我测验了另外两个命令,它们之间的区别在于括号的使用。无论带括号,这两个命令都回传结果。

PS C:\Users> Start-Process -FilePath 'msiexec' -ArgumentList '/IC:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet' -PassThru | Foreach-Object -Process { $_.id }

22980

PS C:\Users> (启动行程 -FilePath 'msiexec' -ArgumentList '/IC:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet' -PassThru -Wait)| Foreach-Object -Process { $_.id }

8064

感谢您对 -wait 自变量的解释。我仍然对括号造成的差异感到困惑。希望得到更多的答复。

uj5u.com热心网友回复:

三个命令的主要区别在于-Wait自变量和括号的使用

Mathias R. Jessen的有用评论为基础:

它是主要使用Start-Process-Wait开关所需要

  • 没有-Wait异步Start-Process运行

  • 如果没有-PassThruStart-Process会产生任何输出

虽然-PassThru品牌Start-Process输出System.Diagnostics.Process代表新推出的程序中,例如除非-Wait该实体的.ExitCode属性没有值还,因为启动的程序通常还没有退出

此外,括号((...))需要太多,因为Start-Process发出的System.Diagnostics.Process实体表示新推出的程序中对管道(由所收到ForEach-Object马上,并且然后等待行程退出。通过使用(...),在分组操作,你迫使等待Start-Process 自己退出,此时Process“实体.ExitCode属性可用的,感谢-Wait

在一般情况下,包装在一个命令(...)的力收集它的输出在前面-其中包括等待它退出-的结果通过管道传递之前(相对于所述(一个接在输出)的行为是默认值,在命令仍在运行时发生)。

因此,以下作业 - 但请参阅底部以获取更简单的替代方案

# Note: With (...), you could also pipe the output to ForEach-Object, as in
#       your question, but given that there's by definition only *one* 
#       output object, that is unnecessary.
(
  Start-Process -PassThru -Wait -FilePath 'msiexec' -ArgumentList '/i C:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet' 
).ExitCode

从上面可以看出,使用两个单独的陈述句也可以作业(假设任何陈述句在执行下一个陈述句之前运行到完成):

$process = Start-Process -PassThru -Wait -FilePath 'msiexec' -ArgumentList '/i C:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet' 
$process.ExitCode 

msiexec.exe不同寻常在于:

  • 它是一个GUI(-subsystem)可执行档案(与控制台(-subsystem)可执行档案相反),因此 - 即使直接呼叫- 也可以异步运行

  • 但它会报告呼叫者可能感兴趣的有意义的行程退出代码,要求呼叫者等待其退出(终止)以确定此退出代码。

顺便说一句:对于呼叫控制台应用程序,Start-Process通常不是正确的工具,除非在不寻常的情况下 - 请参阅此答案


使用with 的一个更简单的替代方法使用直接呼叫 via,这可以确保 (a)同步呼叫和 (b) PowerShell在其自动变量中反映的退出代码msiexecStart-Process -PassThru -Waitcmd /cmsiexec$LASTEXITCODE

cmd /c 'msiexec /i C:\Users\Downloads\Everything-1.4.1.1015.x64.msi -quiet'
$LASTEXITCODE  # output misexec's exit code

注意:如果在msiexec命令列中需要包括PowerShell的变量值,通过一个可扩展的(双引号)的字符串("..."cmd /c代替和-与逐字(单引号)的字符串('...'弦-使用嵌入式双引号周围嵌入自变量,如必要的。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *