Bre*_*yan 41 powershell stderr powershell-2.0
我无法弄清楚如何回显标准错误流并重定向可执行文件的错误流.
我来自Bourne shell和Korn shell背景,我将使用它;
# Write to stderr
echo "Error Message!" >&2
# Redirect stderr to file
/do/error 2>/tmp/err.msg
Run Code Online (Sandbox Code Playgroud)
Kei*_*ill 42
使用Write-Error
写入标准错误.要将stderr重定向到文件使用:
Write-Error "oops" 2> /temp/err.msg
Run Code Online (Sandbox Code Playgroud)
要么
exe_that_writes_to_stderr.exe bogus_arg 2> /temp/err.msg
Run Code Online (Sandbox Code Playgroud)
请注意,PowerShell将错误写为错误记录.如果您想避免错误记录的详细输出,您可以自己写出错误信息,如下所示:
PS> Write-Error "oops" -ev ev 2>$null
PS> $ev[0].exception
oops
Run Code Online (Sandbox Code Playgroud)
-EV
是短(别名)-ErrorVariable
.任何错误都将存储在此参数的参数所指定的变量中.除非我们将错误重定向到,否则PowerShell仍会将错误报告给控制台$null
.
Chr*_*ars 33
你可能想要的是这个:
$host.ui.WriteErrorLine('I work in any PowerShell host')
Run Code Online (Sandbox Code Playgroud)
您可能还会看到以下内容,但它假设您的PS主机是控制台窗口/设备,因此我认为它不太有用:
[Console]::Error.WriteLine('I will not work in the PowerShell ISE GUI')
Run Code Online (Sandbox Code Playgroud)
mkl*_*nt0 30
注意:
这个答案是关于从那里调用PowerShell脚本时从外部世界的角度写入stderr ; 虽然答案是从Windows shell 的角度编写的cmd.exe
,但它同样适用于Unix shell,例如bash
与PowerShell Core结合使用时.
相比之下,从内 Powershell的,你应该使用Write-Error
,如在解释基思·希尔的回答.
遗憾的是,没有统一的方法可以在 PowerShell 和外部工作 - 请参阅我的这个答案进行讨论.
要添加@Chris Sear的好答案:
虽然$host.ui.WriteErrorLine
应该在所有主机中工作,但它(默认情况下)在调用时不会写入stderrcmd.exe
,例如从批处理文件中调用.
[Console]::Error.WriteLine
相反,总是如此.
因此,如果您想编写一个PS脚本,该脚本在调用输出流时可以很好地运行cmd.exe
,请使用以下函数Write-StdErr
,该函数[Console]::Error.WriteLine
在常规PS/cmd.exe
主机(控制台窗口)中使用,$host.ui.WriteErrorLine
否则:
<#
.SYNOPSIS
Writes text to stderr when running in a regular console window,
to the host''s error stream otherwise.
.DESCRIPTION
Writing to true stderr allows you to write a well-behaved CLI
as a PS script that can be invoked from a batch file, for instance.
Note that PS by default sends ALL its streams to *stdout* when invoked from
cmd.exe.
This function acts similarly to Write-Host in that it simply calls
.ToString() on its input; to get the default output format, invoke
it via a pipeline and precede with Out-String.
#>
function Write-StdErr {
param ([PSObject] $InputObject)
$outFunc = if ($Host.Name -eq 'ConsoleHost') {
[Console]::Error.WriteLine
} else {
$host.ui.WriteErrorLine
}
if ($InputObject) {
[void] $outFunc.Invoke($InputObject.ToString())
} else {
[string[]] $lines = @()
$Input | % { $lines += $_.ToString() }
[void] $outFunc.Invoke($lines -join "`r`n")
}
}
Run Code Online (Sandbox Code Playgroud)
在内部,PS具有更比传统的输出流(stdout和stderr),其数量已增加了时间(尝试Write-Warning "I'll go unheard." 3> $null
作为一个例子,而更多的Get-Help about_Redirection
,请注意,链接的网页还没有反映流6
的Write-Information
,在PSv5介绍).
当与外界连接时,PS必须将非传统输出流映射到stdout和stderr.
然而,奇怪的是,PowerShell默认情况下会在调用时将其所有流(包括Write-Host
和$host.ui.WriteErrorLine()
输出)发送到stdoutcmd.exe
,即使将PowerShell的错误流映射到stderr也是合乎逻辑的选择.此行为自(至少)v2起生效,并且仍然适用于v5.1(并且由于向后兼容性可能不会更改).
如果从cmd.exe
以下命令调用它,则可以使用以下命令对此进行验证:
powershell -noprofile -command "'out'; Write-Error 'err'; Write-Warning 'warn'; Write-Verbose -Verbose 'verbose'; $DebugPreference='Continue'; write-debug 'debug'; $InformationPreference='Continue'; Write-Information 'info'; Write-Host 'host'; $host.ui.WriteErrorLine('uierr'); [Console]::Error.WriteLine('cerr')" >NUL
Run Code Online (Sandbox Code Playgroud)
该命令写入所有PS输出流(当您在PSv5之前的版本上运行时,您将看到与Write-Information
PSv5中引入的其他错误消息相关,并且仅cmd.exe
将stdout重定向到NUL
(即,抑制 stdout输出; >NUL
) .
除了(from ,直接写入stderr)之外,您将看不到任何输出- 所有PowerShell的流都被发送到stdout.cerr
[Console]::Error.WriteLine()
也许更奇怪的是,有可能捕获PowerShell的错误流,但只能使用重定向:
如果更改>NUL
为2>NUL
上面的内容,那么PowerShell的错误流和$host.ui.WriteErrorLine()
输出将被禁止; 当然,与任何重定向一样,您也可以将其发送到文件.
(如上所述,[Console]::Error.WriteLine()]
始终输出到stderr,无论后者是否被重定向.)
给出一个更有针对性的例子(再次,运行cmd.exe
):
powershell -noprofile -command "'out'; Write-Error 'err'" 2>NUL
Run Code Online (Sandbox Code Playgroud)
以上只输出out
- Write-Error
的输出被抑制.
总结一下:
没有任何的(cmd.exe
)重定向或只有一个标准输出重定向(>...
或1>...
),PowerShell的将所有的输出流stdout中.
使用stderr重定向(2>...
),PowerShell 有选择地将其错误流发送到stderr(无论stdout是否也被重定向).
作为推论,下面的常用习惯用法不能按预期工作:
powershell ... >data-output.txt
正如人们所预料的那样,这不会在将stderr输出打印到终端时仅向文件发送stdout ; 相反,你必须使用data-output.txt
powershell ... >data-output.txt 2>err-output.tmp; type err-output.tmp >&2; del err-output.tmp
因此,PS意识到了cmd.exe
重定向并故意调整其行为.
(这也可以从PS 在控制台中生成彩色输出,同时在输出重定向到文件时剥离颜色代码.)cmd.exe
如果我遗漏了某些内容和/或某人可以提供此行为的设计理由,请告诉我们.
归档时间: |
|
查看次数: |
34606 次 |
最近记录: |