Capture-Programm stdout und stderr zu getrennten Variablen
Ist es möglich, umleiten von stdout von einem externen Programm eine variable und stderr von externen Programmen, um eine andere variable in einem run?
Beispiel:
$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!";
}
Einem dummen Beispiel allerdings Frage ich mich, ob das möglich ist?
- Sie konnte mit Start-Prozess zu führen myprogram.exe wie hier beschrieben. Es fängt STDOUT und STDERR getrennt.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der einfachste Weg, dies zu tun ist die Verwendung einer Datei für die stderr-Ausgabe, z.B.:
Ich würde auch $LastExitCode auf Fehler überprüfen von native Konsole EXE-Dateien.
stderr.txt
ist wahrscheinlich nur einmal verwendet,New-TemporaryFile
kommt in handlichesEine option ist das kombinieren der Ausgabe von stdout und stderr in einen einzigen Strom, dann filtern.
Daten von stdout werden die Saiten, während stderr erzeugt System.Management.Die Automatisierung.ErrorRecord Objekte.
& myprogram.exe 2>&1 | tee -Variable allOutput
. So erhalten Sie die Ausgabe gedruckt kostenlos, auch halten Sie die Reihenfolge bei der stdout und stderr sind interleaved (keine der anderen Antworten geben). Dies auch nicht durch irgendwelche Dateien, die einen Gewinn in Bezug auf die Leistung und die Minimierung der Dinge, die fehlschlagen können.[Void] (& myprog.exe 2>&1 | tee -Variable allOutput)
und dann$stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }
.Sollten Sie über Start-Prozess mit -RedirectStandardError -RedirectStandardOutput Optionen. Diese anderen post ist ein großartiges Beispiel dafür, wie dies zu tun (Stichprobe aus, dass die post unten):
WaitForExit()
Anruf kommen sollte nachdem dieReadToEnd()
Anrufe.Dies ist auch eine alternative, die ich verwendet zum umleiten von stdout und stderr von Befehl-Linie, während noch mit der Ausgabe während der PowerShell die Ausführung:
Ist es nur noch eine Möglichkeit zu ergänzen, was bereits gegeben.
Halten Sie im Verstand dies mag nicht immer funktionieren, je nachdem, wie das Skript aufgerufen wird. Ich hatte Probleme mit -OutVariable und -ErrorVariable, wenn Sie angerufen werden von einem standard-Befehlszeile anstatt eine PowerShell-Befehlszeile, wie dieser:
Alternative, die scheint zu funktionieren unter den meisten Umständen, ist dieses:
Leider verlieren Sie die Ausgabe auf die Kommandozeile während der Ausführung des Skripts und müsste
Write-Host $stdOutAndError
nach dem Befehl gibt, um es "ein Teil des Datensatzes" (wie ein Teil eines Jenkins-batch-Datei ausführen). Und leider ist es nicht trennen, stdout und stderr.