2015-05-07 22 views
0

我想調用一個任意表達式並將std錯誤重定向到一個變量而不重定向到一個文件。Powershell將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"  
} 

我怎麼可以這樣做,但沒有建立時間輸出的文件?

錯誤的解決方案:

  1. 使用-ErrorVariable開關。計數器例如:

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和$?檢查。反例:

    獲取-服務invalidservice

  • $ lastexitcode等於0,$?等於True,但std錯誤不爲空

    UPD:有人能解釋爲什麼它被低估?我需要創建更明確的解釋嗎?

    UPD2:想法很簡單:將Powershell控制檯中的「紅色」(std error)文本保存在變量中。我收到的命令是一個任意字符串。 例子:

    1. 當我寫「嘗試{拋出‘111’}趕上{}」在PowerShell控制檯會出現在PS主機沒有紅色(錯誤),文本(儘管$誤差不爲空) 。所以如果我在我的代碼中調用這個表達式,我不會在某個變量中保存錯誤。當我編寫「Get-Service notexistingservice」,或「1/0」或「Write-Error 111」時,會出現紅色(錯誤)文本和非空$錯誤。因此,如果我在我的代碼中調用該表達式,我想將錯誤保存在某個變量中。

    回答

    1

    要做到這一點的方法是-errorvariable的通用參數。你的反例僅僅是有效的(我只是猶豫地使用那個單詞),因爲你明確地編碼它不會輸出使用Try/Catch的錯誤,也不會在你的catch中包含任何編碼。你基本上抱怨你告訴PowerShell發送錯誤情況到Catch scriptblock,在那裏你沒有輸出任何東西,然後在沒有輸出時輸出問題。錯誤仍然發生,它按照您所聲明的那樣記錄在錯誤變量中,並且也存儲在$Error中,但由於您沒有在Catch塊中輸出任何內容,因此StdErr重定向不會執行任何操作。

    如果您希望$ ev不包含錯誤,因爲您已更正Catch塊中的問題,那麼還要清除catch塊中的變量。

    $expr = 'try{ throw "1111"}catch{Remove-Variable ev}' 
    

    或者,如果你想標準錯誤包含錯誤文本,請確保您在您的Catch塊輸出:

    $expr = 'try{ throw "1111"}catch{Write-Error $_.Exception.Message}' 
    
    +0

    我更新了帖子的內容,使事情輪。當然,你的代碼可以工作,但不能用於任意表達,即我沒有關於我執行的表達式的信息。 – 2xMax

    +0

    換句話說,我如何區分「嘗試{拋111;}抓{}」和簡單地「扔111」?它們都有非空的$ error變量。我唯一可以使用的是$ ?,但它不適用於「Get-service aaaa」。 – 2xMax