Forum: PC-Programmierung Windows Ausgabeströme umleiten


von Vlad T. (vlad_tepesch)


Lesenswert?

Hi,
ich würde gern die Ausgabeströme eines Kommandozeilentools umleiten.
ich weiß, dass mit > oder 2> die ströme in verschiendene Dateien 
geleitet werden können. Mit 2>&1, kann stderr auf stdout gelenkt werden

mit | kann sie auf die Eingabe eines Prozessen gelenkt werden.

Ich hätte jetzt gerne jedoch den error-kanal vor der ausgabe auf stdout 
noch durch ein grep geschickt

also etwa
tool > file.txt 2| grep x 2>&1

es müsste also der errorkanal auf die Standardeingabe eines 2. Prozesses 
und von da (nun wäre es ja die Standardausgabe des 2. Prozesses) in den 
stdout des gemultiplext werden.
möglicherweise würde das automatisch passieren, wenn das pipen des 
error-Kanal funktionieren würde.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

schnell und schmutzig ohne Pfeife:

tool 1>file.txt 2>grep_roh.txt; grep 'irgendwas' grep_roh.txt > 
gegrept.txt; rm grep_roh.txt; cat file.txt gegrept.txt

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wenn ich dein Vorhaben richtig verstanden habe, geht es in der Bash so:
1
tool 2>&1 >file.txt | grep x

D.h. stdout von tool gelangt direkt in die Datei file.txt, stderr von
tool wird von grep gefiltert, das Ergebnis von grep wird als stdout auf
der Konsole angezeigt.

Da keine Syntaxelemente verwendet werden, die Windows nicht auch kennt,
könnte das auch dort funktionieren.

von Vlad T. (vlad_tepesch)


Lesenswert?

hmm, ich versuchs grad auf meinem Privat PC nachzuvollziehen:

perl-script:
1
for( my $i=0;$i<500; ++$i)
2
{
3
  print STDOUT "stdout $i\n";
4
  print STDERR "stderr $i\n";
5
  sleep(1);
6
}

sobald ich versuche die Standardausgabe umzuleiten kommt gar nix mehr 
an.


Yalu X. schrieb:
> Wenn ich dein Vorhaben richtig verstanden habe, geht es in der Bash so:
> tool 2>&1 >file.txt | grep x
>
> D.h. stdout von tool gelangt direkt in die Datei file.txt, stderr von
> tool wird von grep gefiltert, das Ergebnis von grep wird als stdout auf
> der Konsole angezeigt.

werd ich morgen mal probieren.
Ich hätte aber erwartet, dass grep gar nix mehr bekommt, da ja alle 
ausgaben bereits umgeleitet sind. Die file operatoren haben Vorrang.

wenn man 'dir > test.txt | grep DIR' ausführt kommt aus dem grep auch 
nix mehr raus.

von Vlad T. (vlad_tepesch)


Lesenswert?

Vlad Tepesch schrieb:
> sobald ich versuche die Standardausgabe umzuleiten kommt gar nix mehr
> an.

ok, das lag am fehlenden flushen des Ausgabepuffer.
1
local $| = 1;
2
for( my $i=0;$i<500; ++$i)
3
{
4
  print STDOUT "stdout $i\n";
5
  print STDERR "stderr $i\n";
6
  select(undef, undef, undef, .25);  # .25s warten
7
}

Yalu X. schrieb:
> tool 2>&1 >file.txt | grep x

ok, jetzt scheint die stdout in die Datei zu gehen und der stderr auf 
der stdout zu liegen, den grep verarbeitet, aber wie bekomme ich den 
Output jetzt mit in die file.txt gemultiplext.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Vlad Tepesch schrieb:
> aber wie bekomme ich den
> Output jetzt mit in die file.txt gemultiplext.

Meinst du damit, dass das stdout und das gegreppte stderr am Ende
gemeinsam in file.txt stehen sollen? In der Bash geht das so:
1
{ tool 3>&2 2>&1 1>&3 | grep x; } >file.txt 2>&1

Die ersten drei Redirections vertauschen stdout und stderr. Das neue
stdout (also das ursprüngliche stderr) wird gegreppt. Am Schluss wird
die Ausgabe von grep mit dem stderr (also dem ursprünglichen stdout)
zusammengeführt.

Da grep als eigener Prozess läuft und die Daten an mehreren Stellen
zwischengepuffert werden, werden die am Schluss zusammengeführten
Datenströme nicht zeitlich korrekt ineinandergeschachtelt. Außerdem
müsstest du nachsehen, ob unter Windows die Gruppierung von Befehlen
mittels {} überhaupt möglich ist.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.