Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]9213[/thread]

stdout/stderr eines Kommandos (Backticks) ausgeben: die vordefinierte Perl-Variable $?

Leser: 1


<< >> 6 Einträge, 1 Seite
Joseba
 2007-07-21 15:00
#78735 #78735
User since
2007-07-14
9 Artikel
BenutzerIn
[default_avatar]
Hallo,
ist es richtig, so STDOUT und STDERR von einem ausgeführten Kommando auszuwerten?

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my $cmd = "dir";
my $output = `$cmd 2>&1`;

if ($? != 0)
{
print "stderr: '$output'\n";
}
else
{
print "stdout: '$output'\n";
}


Die vordefinierte Variable $? enthält den Status, der zuletzt von einem system-Aufruf, einer geschlossenen Pipe oder durch Backticks von einem Kindprozess erzeugt wurde.
Quelle: http://de.selfhtml.org/perl/sprache/vordefiniert.htm

Warum kommt bei einem Fehler der Code '256' in '$?'?

Danke für Eure Hilfe,
Joseba
jubei
 2007-07-21 15:40
#78736 #78736
User since
2007-07-19
22 Artikel
BenutzerIn
[default_avatar]
soweit ich weiß, geben die meisten (unix) tools bei einem fehler eine zahl ungleich null zurück, ob das jetzt 256 oder 1 oder was auch immer ist. (die konkrete zahl kann dann allerdings noch information über den konkreten, aufgetretenen fehler geben.)

zu deinem beispiel: was du ja machst, ist dass du stderr auf stdout umleitest. damit enthält dann $output den inhalt beider streams. allerdings machst du einen gedankenfehler, wenn du meinst, dass bei einem fehler NUR auf stderr geschrieben wird, bzw. wenn alles glatt läuft NUR auf stdout geschrieben wird. so werden zb bei nicht-fatalen fehlern oft warnungen auf stderr geschrieben (das tool gibt dann trotzdem 0 zurück), bzw. kann auch schon vor abbruch mit fehlercode etwas auf stdout geschrieben worden sein.

wenn du beides separat auswerten willst, dann zb über zwei temporäre files:
Code: (dl )
foo > foo.stdout 2> foo.stderr

(temp files dann allerdings mit der entprechenden routine aus File::Temp generieren)
jubei
 2007-07-21 16:08
#78737 #78737
User since
2007-07-19
22 Artikel
BenutzerIn
[default_avatar]
sorry, hier eine berichtigung: wie du richtig geschrieben hast, enthält $? den rückgabewert von system(). dieser wiederum ist aber nicht der rüchgabewert des ausgeführten kommandos, sondern von wait(). um den tatsächlichen rückgabewert zu erhalten, musst du 8 positionen nach rechts shiften (sprich durch 256 teilen). in deinem fall hat das kommando also eine 1 zurückgegeben...
jubei
 2007-07-21 16:31
#78738 #78738
User since
2007-07-19
22 Artikel
BenutzerIn
[default_avatar]
...hier noch ein auszug aus perlfunc:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
You can check all the failure possibilities by inspecting $?
like this:

if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
Joseba
 2007-07-21 17:29
#78739 #78739
User since
2007-07-14
9 Artikel
BenutzerIn
[default_avatar]
[quote=jubei,21.07.2007, 13:40]zu deinem beispiel: was du ja machst, ist dass du stderr auf stdout umleitest. damit enthält dann $output den inhalt beider streams. allerdings machst du einen gedankenfehler, wenn du meinst, dass bei einem fehler NUR auf stderr geschrieben wird, bzw. wenn alles glatt läuft NUR auf stdout geschrieben wird. so werden zb bei nicht-fatalen fehlern oft warnungen auf stderr geschrieben (das tool gibt dann trotzdem 0 zurück), bzw. kann auch schon vor abbruch mit fehlercode etwas auf stdout geschrieben worden sein.[/quote]
Vielen Dank für Deine Mühe, an sowas habe ich jetzt gar nicht gedacht.

Ich denke aber, wenn ich nur ein bestimmtes Kommando ausführe und bei diesem genau weiß, was schief laufen könnte und wohin was geschrieben wird, dann kann ich das schon so lassen. Das mit den Temporären Dateien ist zwar die sicherste Methode, aber ich denke für mein Problem im Monent schon zu aufwändig.

Ansonsten muss ich dann wirklich aufpassen, falls sowohl in stdout, als auch in stderr geschrieben werden könnte.
murphy
 2007-07-22 17:14
#78740 #78740
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Wenn man programmatisch auf STDOUT und STDERR eines Subprozesses zugreifen möchte, kann man auch das Standardmodul CPAN:IPC::Open3 verwenden.
When C++ is your hammer, every problem looks like your thumb.
<< >> 6 Einträge, 1 Seite



View all threads created 2007-07-21 15:00.