Capture program stdout and stderr to separate variables

后端 未结 5 1411
小蘑菇
小蘑菇 2020-11-28 10:29

Is it possible to redirect stdout from an external program to a variable and stderr from external programs to another variable in one run?

For example:



        
5条回答
  •  囚心锁ツ
    2020-11-28 11:07

    Separately, preserving formatting

    cls
    function GetAnsVal {
        param([Parameter(Mandatory=$true, ValueFromPipeline=$true)][System.Object[]][AllowEmptyString()]$Output,
              [Parameter(Mandatory=$false, ValueFromPipeline=$true)][System.String]$firstEncNew="UTF-8",
              [Parameter(Mandatory=$false, ValueFromPipeline=$true)][System.String]$secondEncNew="CP866"
        )
        function ConvertTo-Encoding ([string]$From, [string]$To){#"UTF-8" "CP866" "ASCII" "windows-1251"
            Begin{
                $encFrom = [System.Text.Encoding]::GetEncoding($from)
                $encTo = [System.Text.Encoding]::GetEncoding($to)
            }
            Process{
                $Text=($_).ToString()
                $bytes = $encTo.GetBytes($Text)
                $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
                $encTo.GetString($bytes)
            }
        }
        $all = New-Object System.Collections.Generic.List[System.Object];
        $exception = New-Object System.Collections.Generic.List[System.Object];
        $stderr = New-Object System.Collections.Generic.List[System.Object];
        $stdout = New-Object System.Collections.Generic.List[System.Object]
        $i = 0;$Output | % {
            if ($_ -ne $null){
                if ($_.GetType().FullName -ne 'System.Management.Automation.ErrorRecord'){
                    if ($_.Exception.message -ne $null){$Temp=$_.Exception.message | ConvertTo-Encoding $firstEncNew $secondEncNew;$all.Add($Temp);$exception.Add($Temp)}
                    elseif ($_ -ne $null){$Temp=$_ | ConvertTo-Encoding $firstEncNew $secondEncNew;$all.Add($Temp);$stdout.Add($Temp)}
                } else {
                    #if (MyNonTerminatingError.Exception is AccessDeniedException)
                    $Temp=$_.Exception.message | ConvertTo-Encoding $firstEncNew $secondEncNew;
                    $all.Add($Temp);$stderr.Add($Temp)
                }   
             }
        $i++
        }
        [hashtable]$return = @{}
        $return.Meta0=$all;$return.Meta1=$exception;$return.Meta2=$stderr;$return.Meta3=$stdout;
        return $return
    }
    Add-Type -AssemblyName System.Windows.Forms;
    & C:\Windows\System32\curl.exe 'api.ipify.org/?format=plain' 2>&1 | set-variable Output;
    $r = & GetAnsVal $Output
    $Meta2=""
    foreach ($el in $r.Meta2){
        $Meta2+=$el
    }
    $Meta2=($Meta2 -split "[`r`n]") -join "`n"
    $Meta2=($Meta2 -split "[`n]{2,}") -join "`n"
    [Console]::Write("stderr:`n");
    [Console]::Write($Meta2);
    [Console]::Write("`n");
    $Meta3=""
    foreach ($el in $r.Meta3){
        $Meta3+=$el
    }
    $Meta3=($Meta3 -split "[`r`n]") -join "`n"
    $Meta3=($Meta3 -split "[`n]{2,}") -join "`n"
    [Console]::Write("stdout:`n");
    [Console]::Write($Meta3);
    [Console]::Write("`n");
    

提交回复
热议问题