Prüfen ob mein Script schon läuft
Prüfen ob mein Script schon läuft
am 04.04.2006 17:49:23 von Retep Grubanov
Hello,
ich möchte überprüfen, ob eine Instanz von meinem Script schon läuft und
wenn dies so ist, das Script wieder abbrechen. So kann ich bei Cronjobs
verhindern, dass es "Script-Ueberläufer" gibt.
Entspricht der unten aufgeführte Script-Ausschnitt einem guten Perl-Code?
Es grüsst, Retep
#!/usr/bin/perl
use strict;
use warnings;
my $PID = $$;
my ($NAME) = (`ps -up $PID`)[1]; chomp($NAME);
my ($PROC_NAME) = ($NAME =~ /.*\d+\s+(.*)$/);
chomp(my @PROCS = `ps aux`);
foreach my $proc (@PROCS)
{
if ($proc =~ /\S+\s+$PID.*$PROC_NAME$/)
{
print "Mein aktueller Aufruf von $PROC_NAME\n";
next;
} elsif ( $proc =~ /.*\d+\s+$PROC_NAME$/ )
{
print "Weiterer Aufruf von $PROC_NAME\n";
exit;
}
}
sleep 20; # fuer Testzwecke
Re: Prüfen ob mein Script schon läuft
am 04.04.2006 19:35:56 von Tony Muler
Retep Grubanov wrote:
> Hello,
>
> ich möchte überprüfen, ob eine Instanz von meinem Script schon läuft und
> wenn dies so ist, das Script wieder abbrechen. So kann ich bei Cronjobs
> verhindern, dass es "Script-Ueberläufer" gibt.
Mal dumm gefragt: Wenn das Skript von Dir ist ("meinem Script"),
was spricht denn dann dagegen, dass Dein Skript beim Start eine
Datei schreibt; nur so als Anzeige, dass es schon laeuft.
/var/run/meinSkript.pid klingt doch irgendwie vertraut.
Am Ende loescht es diese Datei.
Am Start schaut es erstmal nach, ob es die Datei bereits gibt
und beendet sich, wen dem so ist.
Da faellt mir zum Thema noch flock() ein.
Evtl. muss man an die Millisekunden denken, in denen die
Datei noch nicht existiert, das Skript aber schon rennt.
Kommt aber alles drauf an.
Fuer das, was Du unten in Perl probierst haette ich
wahrscheinlich einfach ein Shell-Skript gemacht.
Nein, awk ist nicht boese.
T.
>
> Entspricht der unten aufgeführte Script-Ausschnitt einem guten Perl-Code?
>
> Es grüsst, Retep
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> my $PID = $$;
>
> my ($NAME) = (`ps -up $PID`)[1]; chomp($NAME);
>
> my ($PROC_NAME) = ($NAME =~ /.*\d+\s+(.*)$/);
>
> chomp(my @PROCS = `ps aux`);
>
> foreach my $proc (@PROCS)
> {
> if ($proc =~ /\S+\s+$PID.*$PROC_NAME$/)
> {
> print "Mein aktueller Aufruf von $PROC_NAME\n";
> next;
> } elsif ( $proc =~ /.*\d+\s+$PROC_NAME$/ )
> {
> print "Weiterer Aufruf von $PROC_NAME\n";
> exit;
> }
> }
>
> sleep 20; # fuer Testzwecke
>
Re: Prüfen ob mein Script schon läuft
am 04.04.2006 21:15:15 von Slaven Rezic
Retep Grubanov writes:
> Hello,
>
> ich möchte überprüfen, ob eine Instanz von meinem Script schon läuft und
> wenn dies so ist, das Script wieder abbrechen. So kann ich bei Cronjobs
> verhindern, dass es "Script-Ueberläufer" gibt.
>
> Entspricht der unten aufgeführte Script-Ausschnitt einem guten Perl-Code?
>
Das Problem lässt sich besser mit einem Lockfile lösen. Siehe
perldoc -f flock
Gruß,
Slaven
--
Slaven Rezic - slaven rezic de
Start a WWW browser - OS independent:
http://user.cs.tu-berlin.de/~eserte/src/perl/WWWBrowser/
Re: Prüfen ob mein Script schon läuft
am 05.04.2006 08:03:44 von Retep Grubanov
Hallo Tony,
vielen Dank für die Anregungen, unten meine Kommentare.
>> ich möchte überprüfen, ob eine Instanz von meinem Script schon läuft und
>> wenn dies so ist, das Script wieder abbrechen. So kann ich bei Cronjobs
>> verhindern, dass es "Script-Ueberläufer" gibt.
>
> Mal dumm gefragt: Wenn das Skript von Dir ist ("meinem Script"),
> was spricht denn dann dagegen, dass Dein Skript beim Start eine
> Datei schreibt; nur so als Anzeige, dass es schon laeuft.
Das Script darf mit unterschiedlichen Übergabeparametern auf dem System
mehrfach am drehen sein. Es darf einfach genau so wie es in der
Prozesstabelle erscheint nur einmal drehen.
> /var/run/meinSkript.pid klingt doch irgendwie vertraut.
> Am Ende loescht es diese Datei.
> Am Start schaut es erstmal nach, ob es die Datei bereits gibt
> und beendet sich, wen dem so ist.
Daran habe ich auch gedacht aber da kann ich nur eine laufende Instanz damit
kontrollieren. Und dann besteht noch das Problem, falls das Script aus
irgendeinem Grund unkontrolliert beendet wird, bleibt das PID-File liegen
und der Job startet nicht mehr.
> Da faellt mir zum Thema noch flock() ein.
> Evtl. muss man an die Millisekunden denken, in denen die
> Datei noch nicht existiert, das Skript aber schon rennt.
> Kommt aber alles drauf an.
Auf die Millisekunden sollte es nicht ankommen.
>
> Fuer das, was Du unten in Perl probierst haette ich
> wahrscheinlich einfach ein Shell-Skript gemacht.
> Nein, awk ist nicht boese.
>
> T.
Ich habe nichts gegen Shell, awk und Konsorte und ich möchte meine Scripte
nur in er Sprache pflegen, nämlich Perl ;-).
Retep
Re: Prüfen ob mein Script schon läuft
am 05.04.2006 11:03:29 von Ingo Menger
Retep Grubanov schrieb:
> Daran habe ich auch gedacht aber da kann ich nur eine laufende Instanz da=
mit
> kontrollieren. Und dann besteht noch das Problem, falls das Script aus
> irgendeinem Grund unkontrolliert beendet wird, bleibt das PID-File liegen
> und der Job startet nicht mehr.
Der neue Prozess muß natürlich das PID-File lesen (in dem die PID des
alten Prozesses zu stehen hat) und mit Signal 0 die Existenz des
anderen Prozesses testen. Das setzt allerdings voraus, daß beide
Prozesse unter derselben uid laufen.
Re: Prüfen ob mein Script schon läuft
am 05.04.2006 14:59:47 von Retep Grubanov
Ingo Menger wrote:
>
> Retep Grubanov schrieb:
>
>
>> Daran habe ich auch gedacht aber da kann ich nur eine laufende Instanz
>> damit kontrollieren. Und dann besteht noch das Problem, falls das Script
>> aus irgendeinem Grund unkontrolliert beendet wird, bleibt das PID-File
>> liegen und der Job startet nicht mehr.
>
> Der neue Prozess muß natürlich das PID-File lesen (in dem die PID des
> alten Prozesses zu stehen hat) und mit Signal 0 die Existenz des
> anderen Prozesses testen. Das setzt allerdings voraus, daß beide
> Prozesse unter derselben uid laufen.
Ja das funktioniert soweit als das Script nur einmal laufen darf. Was ist
aber, wenn das Script mehrmals mit unterschiedlichen
Command-Line-Parametern aufgerufen werden darf, jedoch nur einmal mit den
gleichen Command-Line-Parametern? Ich könnte natürlich eine Reihe PID-Files
anlegen, die nebst der PID auch noch die Übergabeparameter enthalten und
dann beim Script-Start alle Files durchparsen. Diese Lösung finde ich aber
nicht optimal.
Aber was spricht gegen die Lösung die ich im Anfangs-Posting angefügt habe?
Re: Prüfen ob mein Script schon läuft
am 05.04.2006 15:18:39 von Ingo Menger
Retep Grubanov schrieb:
> Ingo Menger wrote:
>
> >
> > Retep Grubanov schrieb:
> >
> >
> >> Daran habe ich auch gedacht aber da kann ich nur eine laufende Instanz
> >> damit kontrollieren. Und dann besteht noch das Problem, falls das Scri=
pt
> >> aus irgendeinem Grund unkontrolliert beendet wird, bleibt das PID-File
> >> liegen und der Job startet nicht mehr.
> >
> > Der neue Prozess muß natürlich das PID-File lesen (in dem die PID d=
es
> > alten Prozesses zu stehen hat) und mit Signal 0 die Existenz des
> > anderen Prozesses testen. Das setzt allerdings voraus, daß beide
> > Prozesse unter derselben uid laufen.
>
> Ja das funktioniert soweit als das Script nur einmal laufen darf. Was ist
> aber, wenn das Script mehrmals mit unterschiedlichen
> Command-Line-Parametern aufgerufen werden darf, jedoch nur einmal mit den
> gleichen Command-Line-Parametern? Ich könnte natürlich eine Reihe PID=
-Files
> anlegen, die nebst der PID auch noch die Übergabeparameter enthalten und
> dann beim Script-Start alle Files durchparsen. Diese Lösung finde ich a=
ber
> nicht optimal.
Stimmt. Besser wäre es, aus der (am besten noch kanonisierten)
Kommandozeile einen Hashwert zu generieren und diesen als Filenamen
für das PID-File zu benutzen.
> Aber was spricht gegen die Lösung die ich im Anfangs-Posting angefügt=
habe?
- Sie verwendet 2mal externe Kommandos.
- Nicht alle ps-Kommandos dieser Welt liefern dieselbe Ausgabe oder
auch nur eine vollständige Ausgabe der kompletten Kommandozeile.
- Ist "perl script.pl -ab" dieselbe Kommandozeile wie "/usr/local/perl
../script.pl -ba"? Wenn ja, dann ist dies nicht in Deiner Lösung
berücksichtigt.
- Das oberflächliche Parsen der ps-Ausgabe ermöglicht zudem einem
fake-Programm, so zu tun, als wäre es Dein Skript, Deine Lösung ist
also nicht allgemeingültig. Das heißt nicht, daß sie nicht in 99%
der Fälle funktioniert, solange gewisse unausgesprochene
Nebenbdingungen gelten. Aber manche mögen solche Lösungen nicht.
Re: Prüfen ob mein Script schon läuft
am 05.04.2006 15:52:12 von Retep Grubanov
Ingo Menger wrote:
>
> Stimmt. Besser wäre es, aus der (am besten noch kanonisierten)
> Kommandozeile einen Hashwert zu generieren und diesen als Filenamen
> für das PID-File zu benutzen.
>
Klingt gut übersteigt aber mein Können. Wie erzeuge ich einen Hashwert?
>> Aber was spricht gegen die Lösung die ich im Anfangs-Posting angefügt
>> habe?
>
> - Sie verwendet 2mal externe Kommandos.
Das könnte noch optimiert.
> - Nicht alle ps-Kommandos dieser Welt liefern dieselbe Ausgabe oder
> auch nur eine vollständige Ausgabe der kompletten Kommandozeile.
Es muss nur auf einer Zielplattform laufen und Portabiliät ist immer super.
> - Ist "perl script.pl -ab" dieselbe Kommandozeile wie "/usr/local/perl
> ./script.pl -ba"? Wenn ja, dann ist dies nicht in Deiner Lösung
> berücksichtigt.
Das Script wird immer aus der Crontab gestartet und so sind die Parameter
immer gleich formatiert.
> - Das oberflächliche Parsen der ps-Ausgabe ermöglicht zudem einem
> fake-Programm, so zu tun, als wäre es Dein Skript, Deine Lösung ist
> also nicht allgemeingültig. Das heißt nicht, daß sie nicht in 99%
> der Fälle funktioniert, solange gewisse unausgesprochene
> Nebenbdingungen gelten. Aber manche mögen solche Lösungen nicht.
Hast du natürlich auch sehr recht, danke für den Hinweis.
Ich hätte mir einfach eine gute Lösung erhofft, die ohne Status-Files
auskommt.
Re: Prüfen ob mein Script schon läuft
am 05.04.2006 16:58:56 von Ingo Menger
Retep Grubanov schrieb:
> Ingo Menger wrote:
> >
> > Stimmt. Besser wäre es, aus der (am besten noch kanonisierten)
> > Kommandozeile einen Hashwert zu generieren und diesen als Filenamen
> > für das PID-File zu benutzen.
> >
>
> Klingt gut übersteigt aber mein Können. Wie erzeuge ich einen Hashwer=
t?
Zum Beispiel mit MD5. Dafür gibt es fertige Module auf CPAN.
> Ich hätte mir einfach eine gute Lösung erhofft, die ohne Status-Files
> auskommt.
Du kannst natürlich auch einen Unix-Socket binden, dann brauchst Du
kein File. Das Problem bei Dir ist natürlich die wahrscheinlich
potentiell sehr große Zahl von Varianten.
Insofern ist Deine Lösung, weil praktisch, wahrscheinlich doch die
beste. Nur schön ist sie halt nicht, IMHO.