代码之家  ›  专栏  ›  技术社区  ›  Simon

PowerShell&cURL-获取JSON响应并检查HTTP响应代码[重复]

  •  1
  • Simon  · 技术社区  · 6 年前

    是否可以在一次运行中将stdout从外部程序重定向到变量,将stderr从外部程序重定向到另一个变量?

    例如:

    $global:ERRORS = @();
    $global:PROGERR = @();
    
    function test() {
        # Can we redirect errors to $PROGERR here, leaving stdout for $OUTPUT?
        $OUTPUT = (& myprogram.exe 'argv[0]', 'argv[1]');
    
        if ( $OUTPUT | select-string -Pattern "foo" ) {
            # do stuff
        } else {
            $global:ERRORS += "test(): oh noes! 'foo' missing!";
        }
    }
    
    test;
    if ( @($global:ERRORS).length -gt 0 ) {
        Write-Host "Script specific error occurred";
        foreach ( $err in $global:ERRORS ) {
            $host.ui.WriteErrorLine("err: $err");
        }
    } else {
        Write-Host "Script ran fine!";
    }
    
    if ( @($global:PROGERR).length -gt 0 ) {
        # do stuff
    } else {
        Write-Host "External program ran fine!";
    }
    

    一个枯燥的例子,但我想知道这是否可能?

    0 回复  |  直到 6 年前
        1
  •  17
  •   Peter Mortensen icecrime    6 年前

    最简单的方法是为stderr输出使用一个文件,例如:

    $output = & myprogram.exe 'argv[0]', 'argv[1]' 2>stderr.txt
    $err = get-content stderr.txt
    if ($LastExitCode -ne 0) { ... handle error ... }
    

    我还将使用$LastExitCode检查本机控制台EXE文件中的错误。

        2
  •  42
  •   Aaron Schultz    9 年前

    来自stdout的数据将是字符串,而stderr生成System.Management.Automation.ErrorRecord对象。

    $allOutput = & myprogram.exe 2>&1
    $stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] }
    $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }
    
        3
  •  9
  •   Peter Mortensen icecrime    6 年前

    other post 有一个很好的例子说明如何做到这一点(从下面的帖子中取样):

    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = "ping.exe"
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = "localhost"
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    $stdout = $p.StandardOutput.ReadToEnd()
    $stderr = $p.StandardError.ReadToEnd()
    Write-Host "stdout: $stdout"
    Write-Host "stderr: $stderr"
    Write-Host "exit code: " + $p.ExitCode
    
        4
  •  4
  •   Peter Mortensen icecrime    6 年前

    这也是我用来重定向命令行的stdout和stderr的另一种方法,同时在PowerShell执行期间仍然显示输出:

    $command = "myexecutable.exe my command line params"
    
    Invoke-Expression $command -OutVariable output -ErrorVariable errors
    Write-Host "STDOUT"
    Write-Host $output
    Write-Host "STDERR"
    Write-Host $errors
    

    这只是补充已经给予的另一种可能性。

    PowerShell -File ".\FileName.ps1"
    

    在大多数情况下,另一个可行的选择是:

    $stdOutAndError = Invoke-Expression "$command 2>&1"
    

    Write-Host $stdOutAndError 在命令返回以使其成为“记录的一部分”(类似于运行Jenkins批处理文件的一部分)之后。不幸的是,它没有将stdout和stderr分开。