1x Skript starten = 2x PID ?

Ulix

Ulix

Ganz am Anfang
Hallo zusammen,

ich hab ein Skript das alle anderen laufenden Instanzen von sich beenden soll:
Code:
for PID in `pgrep $SCRIPTNAME`
do
	if [ $PID -ne $SCRIPTPID ]
	then
		kill $PID > /dev/null 2>&1
	fi
done

Funktioniert auch wunderbar, allerdins findet pgrep immer zwei PIDs des aktuell laufenden Skripts, womit die Schleife danach - die überprüft ob alle Prozesse beendet wurden - ewig wartet bis diese PID beendet wurde, da die ja zu sich selbst gehört. Wenn ich kill -9 mache wird durch die zweite PID natürlich auch das aktuelle Skript beendet, das eigentlich laufen soll.
Hat dieses "Phenomen" einen Namen nachdem ich googlen könnte, is das normal und wie könnt ich das umgehen?

Ulix

P.S.: Is übrigens Solaris 10.
 
kannst du dir vorstellen, dass der prozess "prep $SCRIPTNAME" auf $SCRIPTNAME matcht?

Im übrigen schau dir pidof und killall an.
 
Und schau nach wie man unter dem OS/Shell die PID des aktuellen Prozesses rausbekommt, damit du dann diese nicht killst.
 
kannst du dir vorstellen, dass der prozess "prep $SCRIPTNAME" auf $SCRIPTNAME matcht?
Eigentlich nicht, sonst würde pgrep sich ja immer selbst zusätzlich finden, egal nach welchem Programm man sucht. [edit]Und selbst wenn, spätestens in der nächsten Schleife sollte der pgrep-Prozess dann als erfolgreich beendet erkannt werden und das Problem wäre hinfällig.[/edit]

Im übrigen schau dir pidof und killall an.
Ok hab ich, aber pidof is hier nicht installiert (und ich darf das auch nicht) und killall scheint unter Solaris etwas anderes zu machen:
"killall is used by shutdown(1M) to kill all active processes not directly related to the shutdown procedure." Außerdem braucht es root-Rechte, fällt also somit auch flach.

Und schau nach wie man unter dem OS/Shell die PID des aktuellen Prozesses rausbekommt, damit du dann diese nicht killst.
Hab ich, am anfang vom Skript steht
Code:
SCRIPTNAME=$(basename $0)
SCRIPTPID=$$
und in der Schleife wird der eigene Prozess mit "if [ $PID -ne $SCRIPTPID ]" ausgeschlossen (-ne = ungleich).
Shell is übrigens die Bash.

Wie gesagt es funktioniert, alle anderen Instanzen werden beendet und die eigene nicht, aber das Skript das die anderen beendet hat irgendwie immer zwei PIDs, und daran scheitert es.
Könnte des nen Childprozess sein, und wenn ja für was soll der gut sein?

Ulix
 
Zuletzt bearbeitet:
Wenn du im script einen job startest kann es sein, dass der job als der gleiche prozessname abgelegt wird, ich bin mir in dem Punkt aber nicht sicher.

Falls das der Fall ist kanns sein, dass du mit $SCRIPTPID lediglich den parent job vor beendigung schützt. Post mal das ganze script, vllt wird die sache dann klarer.

Btw bist du dir sicher, dass du für killall root rechte brauchst und nicht das verzeichnis der binary nicht in deinem PATH ist?

Was gibt "echo $(jobs)" vor "for PID in `pgrep $SCRIPTNAME`" aus?
 
Wenn du im script einen job startest kann es sein, dass der job als der gleiche prozessname abgelegt wird, ich bin mir in dem Punkt aber nicht sicher.
Morgen kann ich das mal mit top beobachten.

Falls das der Fall ist kanns sein, dass du mit $SCRIPTPID lediglich den parent job vor beendigung schützt. Post mal das ganze script, vllt wird die sache dann klarer.
Kann ich ja mal machen, aber glaub kaum das da was ist, denn zuerst werden nur Variablen gesetzt, dann kommen paar Funktionen und dann wird schon mit getopts an die angegebene Stelle verzweigt.

Btw bist du dir sicher, dass du für killall root rechte brauchst und nicht das verzeichnis der binary nicht in deinem PATH ist?
So stehts zumindest in man killall (Solaris 10). Und ich wills auch net ausprobieren, weil wenn killall wirklich alle Prozesse zum Runterfahren beendet gibts Ärger.

Was gibt "echo $(jobs)" vor "for PID in `pgrep $SCRIPTNAME`" aus?
Teste ich morgen.

Ulix
 
Also das PID<->PPID Verhältnis würde ich auch für die Ursache halten. Du kannst das ja mit einem einfachen Beispielskript testen, dass z.B. sleep 60 oder so aufruft, damit du genug Zeit hast zu analysieren, welche PIDs es gibt und welche pgrep zurückliefert. Wenn es pidof unter dem Unix gibt könnte das ectl. helfen.

Zum Thema killall: Bloss nicht ausprobieren, vor allem wenn es eine Produktivmaschine ist (da würde ich aber auch solch Skript nicht entwickeln wollen). Das ist das typische Problem wenn Linuxer einem Unixer helfen wollen und Unix nicht kennen. Du hast Recht, killall killt dort alle Prozesse ausser dem aufrufenden. Das gibt es in Linux auch, heisst bei uns aber killall5 (5 weil SysV Init Skripte) und killall ist eins der GNU/Linux Tools die man auf Unix eben nicht immer antrifft. Habe das selbst mal leidvoll erleben müssen. War aber kein Produktiv-Server (zu em Zeitpunkt jedenfalls noch nicht)
 
Ich hab gerade was an ner anderen Stelle im Skript geändert und es neu auf den Server kopiert, und siehe da auf einmal tut es so wie es soll. :think: Ich trau dem Frieden aber nicht ganz, dann wenn ich es dem Chef vorstellen soll kommt garantiert der gleiche Fehler wieder (wär ja nicht das erste mal) X(

Wenn du im script einen job startest kann es sein, dass der job als der gleiche prozessname abgelegt wird, ich bin mir in dem Punkt aber nicht sicher.
Sieht wohl net so aus, zumindest ein Programm das nur ich in dem Skript aufruf hab ich in top gesehen.

Was gibt "echo $(jobs)" vor "for PID in `pgrep $SCRIPTNAME`" aus?
Nix, aber grad tut es ja auch so wie es soll, wenn es wieder auftritt bleib ich da mal dran.

vor allem wenn es eine Produktivmaschine ist
nö nö, ist schon nen Entwicklungserver, aber bin ja nicht alleine auf der Welt.

OK, falls es doch irgendwie am rüber kopieren lag und es jetzt für immer und ewig geht bedanke ich mich für eure Hilfe. Ansonsten komm ich wieder :devil:

Gruß
Ulix
 

Ähnliche Themen

Skript soll nicht doppelt laufen... kill pkill pid cron

Probleme mit IceCast und Ices

Aufbauprobleme beim Desktop beim initialen Login

Zurück
Oben