Powershell:将输出通过管道传递给方法并分离错误流
Powershell: Pipe the output to a method and separate the error stream
我试图将我的脚本的输出通过管道传输到一个单独的方法,并试图在那里分离错误流。这是 pipeline.ps1
Function MyLogs{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline=$True)]
[String[]] $Log
)
Begin {
Write-Verbose "initialize stuff"
# code to initialize stuff
}
Process {
Write-Output " $Log"
}
End {
# code to clean stuff
}
}
#--- pipe the script output to it
& .\MyScript.ps1 | MyLogs
这里是MyScript.ps1
Write-Output "********** This is a normal text message ************* `n`r "
# this would create a divide by zero error
1/0
Write-Warning "example warning"
Write-Output "after the errors"
调用 & .\MyScript.ps1 | MyLogs
不会将错误流通过管道传输到 MyLogs()
但是,错误会显示在控制台中:
PS D:\Learn\powershell> .\pipelines.ps1
VERBOSE: initialize stuff
********** This is a normal text message *************
Attempted to divide by zero.
At D:\Learn\powershell\MyScript.ps1:3 char:1
+ 1/0
+ ~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
WARNING: example warning
after the errors
如果我喜欢 & .\MyScript.ps1 *>&2 | MyLogs
,错误流将被读取为普通文本,我不知道如何将 errors
与 normal text
分开。
主要是,您需要将 all streams (*>&1
) 或至少 Error Stream 重定向到 Success Stream (2>&1
) 以便您的函数可以捕获来自管道的对象。此外,您的函数的参数应采用 [object]
或 [object[]]
而不是 [string[]]
,以便您可以参考来自管道的对象类型。
最后,在 -is
type comparison operator and a switch 的帮助下,您可以创建一个不错的日志记录功能。
using namespace System.Management.Automation
function MyLogs {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline = $True)]
[object] $Log
)
begin {
# code to initialize stuff
}
process {
# this could be reduced to:
# `@{ $Log.GetType().Name = $Log }`
switch($Log) {
{ $_ -is [ErrorRecord] } {
@{ 'Error Record' = $_ }
break
}
{ $_ -is [WarningRecord] } {
@{ 'Warning Record' = $_ }
break
}
{ $_ -is [VerboseRecord] } {
@{ 'Verbose Record' = $_ }
break
}
{ $_ -is [InformationRecord] } {
@{ 'Information Record' = $_ }
break
}
Default {
@{ 'Success Stream' = $_ }
}
}
}
end {
# code to clean stuff
}
}
& {
Write-Output 'This is a normal text message'
1/0
Write-Host 'Information here...'
Write-Warning 'example warning'
Write-Output 'after the errors'
Write-Verbose 'Hello world!' -Verbose
} *>&1 | MyLogs
我会把它留给你进一步更新作为练习,这是你可以从这个例子中得到的输出:
Name Value
---- -----
Success Stream This is a normal text message
Error Record Attempted to divide by zero.
Information Record Information here...
Warning Record example warning
Success Stream after the errors
Verbose Record Hello world!
我试图将我的脚本的输出通过管道传输到一个单独的方法,并试图在那里分离错误流。这是 pipeline.ps1
Function MyLogs{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline=$True)]
[String[]] $Log
)
Begin {
Write-Verbose "initialize stuff"
# code to initialize stuff
}
Process {
Write-Output " $Log"
}
End {
# code to clean stuff
}
}
#--- pipe the script output to it
& .\MyScript.ps1 | MyLogs
这里是MyScript.ps1
Write-Output "********** This is a normal text message ************* `n`r "
# this would create a divide by zero error
1/0
Write-Warning "example warning"
Write-Output "after the errors"
调用 & .\MyScript.ps1 | MyLogs
不会将错误流通过管道传输到 MyLogs()
但是,错误会显示在控制台中:
PS D:\Learn\powershell> .\pipelines.ps1
VERBOSE: initialize stuff
********** This is a normal text message *************
Attempted to divide by zero.
At D:\Learn\powershell\MyScript.ps1:3 char:1
+ 1/0
+ ~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
WARNING: example warning
after the errors
如果我喜欢 & .\MyScript.ps1 *>&2 | MyLogs
,错误流将被读取为普通文本,我不知道如何将 errors
与 normal text
分开。
主要是,您需要将 all streams (*>&1
) 或至少 Error Stream 重定向到 Success Stream (2>&1
) 以便您的函数可以捕获来自管道的对象。此外,您的函数的参数应采用 [object]
或 [object[]]
而不是 [string[]]
,以便您可以参考来自管道的对象类型。
最后,在 -is
type comparison operator and a switch 的帮助下,您可以创建一个不错的日志记录功能。
using namespace System.Management.Automation
function MyLogs {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline = $True)]
[object] $Log
)
begin {
# code to initialize stuff
}
process {
# this could be reduced to:
# `@{ $Log.GetType().Name = $Log }`
switch($Log) {
{ $_ -is [ErrorRecord] } {
@{ 'Error Record' = $_ }
break
}
{ $_ -is [WarningRecord] } {
@{ 'Warning Record' = $_ }
break
}
{ $_ -is [VerboseRecord] } {
@{ 'Verbose Record' = $_ }
break
}
{ $_ -is [InformationRecord] } {
@{ 'Information Record' = $_ }
break
}
Default {
@{ 'Success Stream' = $_ }
}
}
}
end {
# code to clean stuff
}
}
& {
Write-Output 'This is a normal text message'
1/0
Write-Host 'Information here...'
Write-Warning 'example warning'
Write-Output 'after the errors'
Write-Verbose 'Hello world!' -Verbose
} *>&1 | MyLogs
我会把它留给你进一步更新作为练习,这是你可以从这个例子中得到的输出:
Name Value
---- -----
Success Stream This is a normal text message
Error Record Attempted to divide by zero.
Information Record Information here...
Warning Record example warning
Success Stream after the errors
Verbose Record Hello world!