我想调用任意表达式并将std错误重定向到变量而不重定向到文件。
例如,在Powershell中,可以重定向标准错误using 2> operator。使用临时文件,我可以很容易地得到我想要的东西:
#$expr = "1/0" # with std error
#$expr = "2+2" # without stderror
#$expr = "Get-Service invalidsvc" # with stderror
$expr = "try { throw '111' } catch { }" # without std error
$ans = Invoke-Expression $expr -ErrorVariable ev 2> C:\log\stderr.txt
if(cat C:\log\stderr){
Write-Host "Error $ev"
}
我怎样才能这样做,但没有创建时间输出文件?
错误的解决方案:
Invoke-Expression $expr -ErrorVariable ev 2> C:\aaa\file1.txt
$expr = "try { throw '111' } catch { }"
Write-Host "Error $ev" # will output error, but std error is empty
$ LASTEXITCODE和$?校验。反例:
Get-Service invalidservice
$ lastexitcode等于0,$?等于True,但是std错误不为空
UPD :有人可以解释为什么会被投票?我是否需要创建更清晰的解释?
UPD2 :想法很简单:将Powershell控制台中的“红色”(标准错误)文本保存在变量中。我收到的命令是一个任意字符串。 例子:
当我在Powershell控制台中写“try {throw'111'} catch {}”时,PS控制台中没有红色(错误)文本(尽管$ error不是空的)。因此,如果我在代码中调用该表达式,则不会在某个变量中保存错误。
当我写“Get-Service notexistingservice”,或“1/0”或“Write-Error 111”时,会出现红色(错误)文本和非空$错误。因此,如果我在代码中调用该表达式,我希望将错误保存在某个变量中。
答案 0 :(得分:1)
执行此操作的方法是-errorvariable
常用参数。您的计数器示例仅有效(我只是犹豫地使用该单词),因为您已明确编码,因为它不会使用Try/Catch
输出错误,并且不会在您的catch中包含任何编码。您基本上抱怨说,您告诉PowerShell将错误案例发送到Catch
脚本块,您没有输出任何内容,然后在没有输出任何内容时出现问题。仍然会发生错误,它会记录在您应该声明的错误变量中,并且也存储在$Error
中,但由于您没有在Catch
块中输出任何内容,因此您的StdErr重定向没有任何内容做。
如果您希望$ ev不包含错误,因为您更正了Catch
块中的问题,那么也要清除catch块中的变量。
$expr = 'try{ throw "1111"}catch{Remove-Variable ev}'
或者,如果您希望StdErr包含错误文本,请确保在Catch
块中包含该输出:
$expr = 'try{ throw "1111"}catch{Write-Error $_.Exception.Message}'
答案 1 :(得分:1)
将标准输出和标准错误保存到单独的变量中。没有美元符号,它将无法正常工作(来自Windows Powershell in Action)。
$err = $( $output = get-childitem foo3 ) 2>&1
答案 2 :(得分:0)
我知道这是一个非常老的问题,但是我也遇到了同样的问题,并且想分享我最终得出的结论。
$error.clear()
$List = New-Object PSObject
Invoke-Command -ComputerName $server -ScriptBlock {
$smbv1 = (Get-SmbServerConfiguration | Select EnableSMB1Protocol)
$smbv1 | Select-Object EnableSMB1Protocol} -OutVariable List
foreach($item in $list.EnableSMB1Protocol){
if($error -ne $null){
$item = "unknown"
$msg = $error.Exception.Message
ac .\smb1errors.txt "$Server, $msg"
}
由于$ error变量是一个.NET对象,为了清除它,我需要将其传递给参数()。然后,我执行了我的代码,在本例中检查SMBv1服务,并测试$ error是否仍然为$ null。如果$ error变量包含内容,则将其包含在变量中。 $ msg = $ error.Exception.Message