From: martin@mwtech.UUCP (Martin Weitzel)
Newsgroups: de.comp.os.unix
Subject: Re: Suche Shellscript/ C-Progr. zum automatischen Prozesskill
Date: 12 Jan 93 12:50:31 GMT
Reply-To: martin@mwtech.UUCP (Martin Weitzel)
Organization: MIKROS Systemware, Darmstadt/W-Germany

In article <1ifo0jINNfaq@smurf.sub.org> urlichs@smurf.sub.org (Matthias Urlichs) writes:
>In de.comp.os.unix, article <1715@stanny.GUN.de>,
>  stefan@stanny.GUN.de (Stefan Haefs) writes:
>> 
>> Ich suche fuer SCO-Unix ein shell-script fuer root, welches automatisch 
>> zu einer bestimmten Zeit aus der Prozessliste einen Programmnamen raussucht
>> und die zugehoerige Prozessnummer killt. (oder C-Programm)
>> 
>Kann ja nicht so schwer sein....
>
>ps -ef|grep NAME |grep -v grep|while read a b c ; do kill $b ; done
>#ps -ef
>#     UID   PID  PPID  C    STIME TTY      TIME COMMAND
>#    root     0     0  0 16:22:06 ?        0:01 swapper
>#    root     1     0  0 16:22:06 ?        1:04 /etc/init 
>#    root     2     0  0 16:22:06 ?        0:45 vhand
>#    root     3     0  0 16:22:06 ?        0:00 kmemd
>#    root   243     1  0 16:22:50 ?        0:03 /usr/local/etc/console 
>#    root     6     1  0 16:22:07 ?        0:46 /etc/fidd 
>... /etc/pp

Ich verwende fuer solche (und aehnliche Zwecke) folgendes, nach meinem
persoenlichen Geschmack recht flexible Konstrukt:

	cmdpid=`/bin/ps -ef | {
	read v && while read $v rest
	do 
		case $COMMAND in NAME) echo $PID; esac
				 ####---- Name des zu beendenden Kommandos
	done
	}`

(Das obige ist ein Auszug aus einem Skript, in dem es lediglich darum geht,
festzustellen ob das Kommando NAME ueberhaupt laeuft.  Will man das Kommando
gleich beenden, eruebrigt sich natuerlich die Zuweisung an die Hilfsvariable
"cmdpid" und man kann das "echo" gleich durch ein "kill" ersetzen.0

Ich bitte nun erst einmal alle, die noch nicht verstanden habe, WARUM
ich oben die Shell-Variablen PID und COMMAND verwenden kann, scheinbar
ohne dass eine Zuweisung erfolgt, ueber das obige Skript nachzudenken.
(Hinweis: Es wurde direkt aus einer Shell-Prozedur in diesen Artikel
kopiert und enthaelt KEINEN Tippfehler, auch wenn eine bestimmte Stelle
vielleicht so aussehen mag ...)

Alles klar? Dann weiter mit einer guten und einer schlechten Nachricht.

Zunaechst die gute: Hat man das Prinzip erst einmal verstanden, dann ist
es natuerlich absolut easy, alle Prozesse zu killen, die z.B. einem
bestimmten User gehoeren, an einer bestimmten TTY haengen, Kombinationen
davon usw.

Nun die schlechte, und das ist eine Sache, die mich auch in analogen
Faellen immer wieder aergert: Irgend so ein Deppi fand es gut, bei lange
laufenden Prozessen ploetzlich das STIME-Feld so zu aendern, dass darin
white space vorkommt:

     UID   PID  PPID  C    STIME TTY      TIME COMMAND
    root     0     0  0  Dec 29  ?        0:01 sched
    [...]
  martin   255     1  0 01:25:50 vt07     0:01 -sh 
    [...]

Und das ist natuerlich ABSOLUT TOEDLICH fuer Programme, die erwarten,
dass ein bestimmtes Feld einen bestimmten Inhalt hat, ganz egal ob
man nun mit dem oben gezeigten Trick "namensweise" liest, oder ob z.B.
ein AWK-Skript davon ausgeht, dass es in $7 die Rechenzeit eines
Prozesses findet, denn alles, was noch hinter STIME kommt, verschiebt
sich ja evtl. um ein Feld :-(

Ich habe in der Tat lange gebraucht, bis ich drauf kam, warum ein bestimmtes
auto-kill-Skript manchmal nicht richtig funktionierte.  Der Rechner laeuft
hier halt rund um die Uhr und neu gebootet wird normalerweise nur, wenn mal
ein neuer Kernel gebunden wird, und beim Test meines Skriptes liefen die
Kommandos halt nie lange genug.

Um das Problem mit den unterschiedlichen Formaten des STIME-Feldes
in den Griff zu kriegen, musste ich leider die "elegante" obige Loesung
ein wenig ergaenzen:

	HHMMSS='[0-9][0-9]:[0-9][0-9]:[0-9][0-9]'
	cmdpid=`/bin/ps -ef | {
	read v && while read $v rest r2
	do 
		case $STIME in $HHMMSS);;*) COMMAND=$rest; esac
		case $COMMAND in NAME) echo $PID; esac
				 ####--- nur symbolisch gemeint, wie oben
	done
	}`

Will man auch auf STIME, TTY und TIME symbolisch zugreifen, muss man ggf.
auch die "verschieben" (STIME=$STIME-$TTY; TTY=$TIME; TIME=$COMMAND).

Abschliessend deshalb vielleicht eine Bitte an alle, die neue UNIX-Kommandos
ersinnen, welche eine Ausgabe erzeugen (fuer die "Designer" von "ps" oder
auch "ls -l" kommt meine Bitte leider zu spaet):  Denkt dran, dass man eine
Kommandoausgabe nicht nur ANSEHEN, sondern manchmal auch WEITERVERARBEITEN
will.  Ob in unter diesem Aspekt Ueberschriften zweckmaessig sind, sei
dahingestellt.  Immerhin kriegt man eine stoerende Ueberschrift noch
"relativ" leicht weg (oder kann sie wie im obigen Fall sogar nuetzlich
verwenden), aber es ist aeusserst laestig, wenn das Format der Ausgabezeilen
inhaltsabhaengig variiert.  Zumindest sollte sich in diesem Fall nicht die
Zahl der durch white-space getrennten Felder aendern, da man dann zur
Weiterverarbeitung mit UNIX-Tools wie "awk" oder "cut -f" die Faelle erst
muehsam auseinandersortieren muss.  (Sehr vorbildlich waere es IMHO,
Kommandos aehnlich dem `prs' von SCCS mit einer Option auszustatten, mit
der man das Format der Ausgabezeilen vollkommen frei bestimmen kann.)
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83