standard qué por mensajes los generados error envían dónde defecto comandos and windows powershell command-line stdout stderr

windows - qué - stdout linux



Powershell: Capture el programa stdout y stderr para separar las variables (4)

¿Es posible redirigir stdout de un programa externo a una variable y stderr de programas externos a otra variable en una ejecución?

por ejemplo:

$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!"; }

Un ejemplo aburrido, sin embargo, me pregunto si eso es posible.


Debería utilizar las opciones Start-Process con -RedirectStandardError -RedirectStandardOutput. Esta otra publicación tiene un gran ejemplo de cómo hacer esto (tomada de la siguiente publicación):

$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


Esta es también una alternativa que he usado para redirigir stdout y stderr de una línea de comando mientras todavía muestra el resultado durante la ejecución de 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

Otra posibilidad más para complementar lo que ya se dio.

Tenga en cuenta que esto no siempre funciona dependiendo de cómo se invoca el script, he tenido problemas con -OutVariable y -ErrorVariable cuando se invoca desde una línea de comandos estándar en lugar de una línea de comandos de PowerShell como esta:

PowerShell -File "./FileName.ps1"

Una alternativa que parece funcionar en la mayoría de las circunstancias es esta:

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

Desafortunadamente, perderá salida a la línea de comando durante la ejecución del script y tendrá que Write-Host $stdOutAndError después de que el comando regrese para hacerlo "parte del registro" (como una parte de un archivo por lotes de Jenkins). Y lamentablemente no separa stdout y stderr.


La forma más sencilla de hacerlo es usar un archivo para la salida de stderr, por ejemplo:

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

También usaría $ LastExitCode para verificar si hay errores de las extensiones nativas de la consola.


Una opción es combinar la salida de stdout y stderr en una sola transmisión, luego filtrar.

Los datos de stdout serán cadenas, mientras que stderr produce objetos System.Management.Automation.ErrorRecord.

$allOutput = & myprogram.exe 2>&1 $stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] } $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }