如何在管道脚本时使用诸如here-strings之类的多行命令?

时间:2017-02-26 14:48:16

标签: powershell multiline herestring

使用 PowerShell 可执行文件的-Command -选项时,我遇到了以下限制:

Write-Host "SETUP"
Set-PSDebug -Trace 2
Write-Host "TEST ONE"
$foo = "BAR"
Write-Host "TEST TWO"
Get-ChildItem
Write-Host "TEST THREE"
$bar = @"
BAZ
"@
Write-Host "DONE"

如果我将之前的内容保存到test.ps1并执行cat .\test.ps1 | powershell -Command -,我会得到以下输出:

SETUP
DEBUG:    1+  >>>> Write-Host "TEST ONE"
DEBUG:     ! CALL function '<ScriptBlock>'
TEST ONE
DEBUG:    1+  >>>> $foo = "BAR"
DEBUG:     ! CALL function '<ScriptBlock>'
DEBUG:     ! SET $foo = 'BAR'.
DEBUG:    1+  >>>> Write-Host "TEST TWO"
DEBUG:     ! CALL function '<ScriptBlock>'
TEST TWO
DEBUG:    1+  >>>> Get-ChildItem
DEBUG:     ! CALL function '<ScriptBlock>'


    Directory: C:\empty


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       26/02/2017     15:39            179 test.ps1


DEBUG:    1+  >>>> Write-Host "TEST THREE"
DEBUG:     ! CALL function '<ScriptBlock>'
TEST THREE

如您所见,Write-Host "DONE"行的输出永远不会显示。

因此,在逐行评估时, here strings 似乎正在发生一些事情。为什么会这样?

更重要的是,有没有办法让 here strings 在这种情况下工作?

1 个答案:

答案 0 :(得分:1)

注意:以下内容适用于Windows PowerShell v5.1.14393.693和PowerShell Core v6.0.0-alpha16。

PetSerAl,就像他经常做的那样,在对问题的评论中提供关键指针(后来,通过评论,也提供了最简单的修复):

  

似乎问题不在于here-strings [本身],而是多线命令[一般]。

-Command -要求 得到认可。

here-string根据定义是一个多行命令的实例,这就是你遇到问题的原因。

因此,要解决包含多行命令的脚本中的问题,请在 end <\ n>插入一个空行 < / p>

Write-Host "SETUP"
Set-PSDebug -Trace 2
Write-Host "TEST ONE"
$foo = "BAR"
Write-Host "TEST TWO"
Get-ChildItem
Write-Host "TEST THREE"
$bar = @"
BAZ
"@
Write-Host "DONE"  # IMPORTANT: Note the empty line below.
 

为什么这有必要?

可以在powershell自己的CLI帮助(powershell -?)中找到答案,其-Command参数的描述以(强调添加)开头:< / p>

  

执行指定的命令(以及任何参数),就像它们一样       在Windows PowerShell命令提示符下键入

未加载PSReadLine模块,当您以交互方式输入多行命令时,您需要 extra 输入按键以提交条目,以便让PowerShell知道您何时完成输入命令。

注意:PSReadLine模块,它成为W10 / PSv5中交互式 PowerShell会话的标准组成部分,谢天谢地消除对此的需求额外的击键,因为无论命令是否完整,从输入内容的语法中推断出
但是,当您通过PSReadLine传递命令时,-Command - 如果您想体验PowerShell 本身如何解析交互式会话中的多行命令,请先执行Remove-Module PSReadLine。 功能

不幸的是,当-Command -用于通过 stdin 提供命令时会应用相同的逻辑,所以你必须模拟额外的输入键,输入中带有空行,尽管PetSerAl在最后发现空行 就足够了。

如果您希望此行为发生变化和/或希望获得-File -脚本等输入的适当支持,请考虑在此处发表您的声音{ {3}}