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

Prozessid eines mit system ausgeführten befehls



<< >> 9 Einträge, 1 Seite
mordur
 2007-08-06 18:24
#97657 #97657
User since
2003-09-25
182 Artikel
BenutzerIn
[Homepage] [default_avatar]
moins,

wie ermittele ich die Prozessid eines durch system() ausgeführten befehls?
oder kann man es anders machen?
Code: (dl )
system("print STDERR Hallo!"); #jetzt bräuchte ich die PID des print-Befehles


gruß mordur
sid burn
 2007-08-06 18:44
#97659 #97659
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Kannst du Bitte genau sagen was du machen möchtest?

1) Dein Befehl den du in System ausführst sieht für mich nicht aus, als das es das geben würde. Unter GNU/Linux gibt es zwar ein print Befehl der Funktioniert so nicht. Welches OS nutzt du? Für mich sieht es so aus, als wenn du Perl Code ausführen möchtest.

2) Wenn du system() ausführst dann wartet dein aktueller Prozess solange bis der Befehl in system() ausgeführt und beendet wurde. Von daher nach dem system() läuft das programm nicht mehr, und die PID die der Befehl hatte, ist auch schon wieder längst freigegeben. Von daher macht das ganze was du willst wenig Sinn.


Also schreib bitte was dein ziel ist und was du machen möchtest. Anstatt nach einer Lösung zu fragen, die möglicherweise gar nicht die Lösung für dein Problem ist.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
RPerl
 2007-08-06 19:11
#97660 #97660
User since
2006-11-26
384 Artikel
BenutzerIn

user image
Wenn ich das richtig interpretiere, dann willst Du, wenn du z.B. system("ls") machst, die Prozessid von dem ausfuehrenden system()? Wenn ja, dann geht das nur ueber einen eigenen thread, welcher system() ausfuehrt.
Aber wenn Du ein extrenes Programm mit system() startest, kannst du auch die PID holen mit einigen Modulen oder von Hand per ps aux wieder in Kombination mit einem system().
betterworld
 2007-08-06 22:47
#97673 #97673
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Eine einfache Variante, um einen Prozess um Hintergrund zu starten und seine PID zu kriegen, ist diese hier:
Code (perl): (dl )
my $pid = open '-|', my $pipe, 'ls', '-r' or die $!;

Je nach dem, ob man dem Prozess STDOUT oder STDIN wegnehmen will, kann man statt '-|' auch '|-' verwenden. Wenn man ihm beides lassen will, geht meine Variante nicht (...nicht so einfach). Mehr dazu in perldoc -f open. Alternativ perldoc -f fork.

Aber wie sid burn schon angedeutet hat, willst Du wahrscheinlich sowieso keinen externen Befehl ausführen, es sei denn, in Deinem Code-Beispiel da oben ist Dir ein ganz arger Copy&Paste-Fehler unterlaufen.
RPerl
 2007-08-06 22:57
#97675 #97675
User since
2006-11-26
384 Artikel
BenutzerIn

user image
Boah das wusste ich garnicht. :o
Das heisst, diese Zeile:

Code (perl): (dl )
my $pid = open '-|', my $pipe, 'ls', '-r' or die $!;


..gibt die PID von dem Befehl "ls -r" aus?


Aber er will das ganze ja fuer system(), vllt kann er nicht auf open() zurueckgreifen?

Gruß und Danke!

rPerl
sid burn
 2007-08-07 00:33
#97683 #97683
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
@RPerl
Grrrr....

Also ich erkläre das Beispiel mal etwas genauer:
Code (perl): (dl )
1
2
system('ls -l');
print "Hallo, Welt!\n";


In den oberen Mini Stück code wird zuerst ein system() aufgerufen. Dieses ruft "ls -l" auf. Und jetzt kommt der knackpunkt. Wärenddessen läuft dein Perl Programm nicht weiter! Ein aufruf von system() führt dazu das dein komplettes Programm solange stehen bleibt bis das Kommando ausgeführt wurde und sich beendet, erst danach fährt dein Perl Programm fort.

Wenn du anstatt "ls -l" jetzt "gimp" aufrufst, und du 3 Stunden lang ein Bild in gimp malen würdest, dann würde dein Programm auch 3 Stunden lang warten bis gimp beendet ist.

Wenn es jetzt Möglich wäre und du würdest wirklich die PID heraus bekommen für system() welchen Nutzen hat dir diese PID dann noch? Kurz gesagt gar kein. Du magst dann die PID haben, aber der Prozess mit dieser PID existiert schon lange nicht mehr. Das einzige was du ausgeben könntest wäre: "Ich habe ein Process mit der PID $PID erzeugt. Allerdiengs existiert dieser Process nicht mehr, von daher ist diese Information sowieso unbrauchbar".

Und da so eine Ausgabe unbrauchbar ist, ist mir kein weg bekannt die PID von einem system() Befehl heraus zu bekommen. Zumal es sowieso keinen Sinn macht diese zu Wissen.

Das was höchstens von Interesse wäre, wäre z.B. der Rückgabewert des Programmes, damit kann man dann Prüfen ob das Programm erfolgreich gelaufen ist, oder nicht. Der Rückgabewert steht in der Specialvariable $?.

Wenn er die Rückgabe des Programmes lesen möchte, wäre der qx() Operator das richtige. Möchte er einen Prozess starten und die Ausgabe Parallel abarbeiten, dann das Beispiel von betterworld.

Es kann aber immer noch Beispiele geben wo all das unbrauchbar ist. Unter umständen können dann Module wie IPC::Open2 oder IPC::Open3 helfen, oder man macht händisch alles mit fork(). Allerdiengs muss der Threadersteller erstmal wieder genauer erklären was er überhaupt machen möchte.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
betterworld
 2007-08-07 05:03
#97685 #97685
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Also, es ist ja nun nicht so, dass man mit system keine Hintergrundprozesse starten kann. system('gimp &') funktioniert zumindest auf unixoiden Systemen. Aber spätestens wenn man bei so etwas wie
Code (perl): (dl )
my $pid = qx(sh -c 'echo -n \$\$; exec gimp >/dev/null' &);

ist, ist der Code hoffnungslos fürchterlich geworden. Da lieber mit fork etc arbeiten.

Übrigens habe ich gerade mal ExterneProgramme im Wiki angefangen (ich hoffe, das gab es nicht vorher schon in einer versteckten Ecke...)
mordur
 2007-08-07 11:16
#97688 #97688
User since
2003-09-25
182 Artikel
BenutzerIn
[Homepage] [default_avatar]
sid burn+2007-08-06 22:33:12--
@RPerl
Grrrr....

Also ich erkläre das Beispiel mal etwas genauer:
Code (perl): (dl )
1
2
system('ls -l');
print "Hallo, Welt!\n";


In den oberen Mini Stück code wird zuerst ein system() aufgerufen. Dieses ruft "ls -l" auf. Und jetzt kommt der knackpunkt. Wärenddessen läuft dein Perl Programm nicht weiter! Ein aufruf von system() führt dazu das dein komplettes Programm solange stehen bleibt bis das Kommando ausgeführt wurde und sich beendet, erst danach fährt dein Perl Programm fort.

Wenn du anstatt "ls -l" jetzt "gimp" aufrufst, und du 3 Stunden lang ein Bild in gimp malen würdest, dann würde dein Programm auch 3 Stunden lang warten bis gimp beendet ist.

Wenn es jetzt Möglich wäre und du würdest wirklich die PID heraus bekommen für system() welchen Nutzen hat dir diese PID dann noch? Kurz gesagt gar kein. Du magst dann die PID haben, aber der Prozess mit dieser PID existiert schon lange nicht mehr. Das einzige was du ausgeben könntest wäre: "Ich habe ein Process mit der PID $PID erzeugt. Allerdiengs existiert dieser Process nicht mehr, von daher ist diese Information sowieso unbrauchbar".

Und da so eine Ausgabe unbrauchbar ist, ist mir kein weg bekannt die PID von einem system() Befehl heraus zu bekommen. Zumal es sowieso keinen Sinn macht diese zu Wissen.


jepp, das hast du richtig erkannt. mittlerweile habe ich auch gemerkt, das ich die PID nicht wirklich brauchen kann, weil der Prozess ja bereits zu Ende ist, wenn mein Perlprogramm weiter läuft. So hab ich wohl eher ein strukturelles Problem... ;-)
RPerl
 2007-08-08 13:47
#97770 #97770
User since
2006-11-26
384 Artikel
BenutzerIn

user image
@sid burn: wo bezweifle ich das? Außerdem kann man das sehr wohl mit & und nohup machen. Siehe betterworld's posting... junge, junge
<< >> 9 Einträge, 1 Seite



View all threads created 2007-08-06 18:24.