PID beim Prozessstart ermitteln

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Peter Thomassen
Beiträge: 19
Registriert: 01.01.2004 16:02:44

PID beim Prozessstart ermitteln

Beitrag von Peter Thomassen » 17.02.2007 18:55:07

Hi!

Angenommen, ich starte in einem Script irgendein Programm, z.B. sh. Dann wäre es nützlich, direkt beim Aufruf die PID von sh ermitteln zu können. Würde man das erst hinterher per pgrep oder so machen, kommt es ja Missverständnissen, wenn mehrere sh-Prozesse laufen.

Habt ihr da Ideen?

Danke!
Peter
Zuletzt geändert von Peter Thomassen am 17.02.2007 21:11:48, insgesamt 3-mal geändert.

nepos
Beiträge: 5238
Registriert: 05.01.2005 10:08:12

Beitrag von nepos » 17.02.2007 18:58:27

Die Shell-Variable $$ enthält die PID der aktuellen Shell.

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 17.02.2007 19:06:51

und die Variable $! enthält die PID vom letzten Background - Prozess

Gruß
gms
Zuletzt geändert von gms am 17.02.2007 19:08:31, insgesamt 1-mal geändert.

Peter Thomassen
Beiträge: 19
Registriert: 01.01.2004 16:02:44

Beitrag von Peter Thomassen » 17.02.2007 19:07:37

Danke! gms hatte die Lösung :-)

Peter

Peter Thomassen
Beiträge: 19
Registriert: 01.01.2004 16:02:44

Beitrag von Peter Thomassen » 17.02.2007 21:16:34

Es tut sich ein weiteres Problem auf. Mein Script test.sh ist einfach:

Code: Alles auswählen

#!/bin/sh
inotifywait -e create ... &
echo $! > /var/run/test.pid
In /var/run/test.pid steht nun aber nicht die PID von inotifywait; die Zahl ist um 1 erhöht. Ich habe mein Script mal mittels sleep am Ende angehalten und festgestellt, dass die PID in der Datei die PID meines Scripts ist.

Es scheint also folgendes Verhalten vorzuliegen:
- test.sh wird gestartet, z.B. PID 100
- inotifywait wird gestartet, z.B. PID 101
- echo $! schreibt "102" in /var/run/test.pid. Durch Tests lässt sich ermitteln, dass dies die neue PID von test.sh ist.

Ist das nicht komisch? Wieso bekommt test.sh eine neue PID?

Danke,
Peter

Benutzeravatar
meandtheshell
Beiträge: 4054
Registriert: 14.01.2005 17:51:30

Beitrag von meandtheshell » 17.02.2007 22:05:53

Was auch logisch ist - dein Fehler ist $! im script abzufragen.

Code: Alles auswählen

starte scirpt und schicke darin etwas in den background && echo $!
wäre richtig. Was genau willst du eigentlich machen? Evtl. kannst du mit "pidof" und dem absoluten Pfad etwas erreichen.

Eines lass dir aber gesagt sein - für zuverlässige Information zur PID oder PPID eines Prozesses musst du die Shell verlassen und C Code schreiben. Die shell kennt keine lock mechanismen (semaphores etc.).

markus

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 17.02.2007 22:39:29

das Problem habe ich nicht ganz verstanden und läßt sich bei mir auch nicht reproduzieren

Code: Alles auswählen

root@gms1:~# cat x.sh
#!/bin/bash
MYPROG=inotifywait

function searchpid() {
  local LPID=$1
  echo -n "searching for pid=$LPID: "
  local PS=`ps -ef | grep -w "$LPID" | grep -w "$MYPROG"`
  if [ -n "$PS" ]; then
    echo "found"
    echo "  $PS"
  else
    echo "not found"
  fi
}

$MYPROG -e create /tmp &
MYPID=$!
sleep 1
searchpid $MYPID
echo "kill $MYPID"
kill -9 "$MYPID"
sleep 1
searchpid "$MYPID"
root@gms1:~#
root@gms1:~# ./x.sh
Setting up watches.
Watches established.
searching for pid=7087: found
  root      7087  7086  0 22:38 pts/3    00:00:00 inotifywait -e create /tmp
kill 7087
./x.sh: line 22:  7087 Getötet                $MYPROG -e create /tmp
searching for pid=7087: not found
Gruß
gms

Peter Thomassen
Beiträge: 19
Registriert: 01.01.2004 16:02:44

Beitrag von Peter Thomassen » 17.02.2007 23:05:05

Tag,

habe das Problem lösen können; die PID-Erhöhung wurde dadurch verursacht, dass der Output von inotifywait per Pipe weitergeleitet wurde und die erhöhte PID sich dann auf das Pipe-Kommando bezog. meandtheshell, es klappt auch innerhalb desselben Scripts.

Das Script ist übrigens dazu da, inotifywait als Daemon zu starten (leider gibt's anscheinend keine daemonize-Option) und die Spam-Ordner in verschiedenen Maildirs auf neuen Inhalt zu untersuchen. Wenn nun jemand etwas in seinen Spam-Ordner schiebt, wird sa-learn aufgerufen, damit SpamAssassin sich die Kennzeichen der betroffenen Mail merkt. Der Vorgang wird geloggt. Anschließend wird die Mail in den Trash-Ordner verschoben. Die PID wird benötigt, um ein PID-File für start-stop-daemon anzulegen.

Die Sache sieht nun so aus:

Code: Alles auswählen

#!/bin/sh
(nohup inotifywait -q -e create -m --format '%w %f' /home/pop*/Maildir/.Spam/cur/ & echo $! > /var/run/imap2sa-learn.pid) | while read base file; do su -c "echo -n `date`' $base$file '; sa-learn --spam" -s /bin/sh Debian-exim < $base$file >> /root/imap2sa-learn/spam; mv $base$file $base/../../.Trash/cur/; done </dev/null &
Der Kern ist richtig, es funktioniert ja auch. Ich bin mir aber nicht sicher, an welchen Stellen es syntaktisch korrekt ist, zur Verbesserung der Übersichtlichkeit einen Zeilenumbruch (samt \) einzufügen.

"nohup" vorne und "</dev/null" hinten scheinen nötig zu sein, damit die (SSH-)Shell beim Logout nicht hängen bleibt. Hat eine Weile gedauert, bis ich dahinter gekommen bin. Es erscheint mir aber komisch, dass einmal nohup und einmal </dev/null nötig sein soll. Verwende ich aber in beiden Fällen "nohup" oder "</dev/null", bleibt die Shell trotzdem hängen. Es scheint nur in dieser Konstellation zu funktionieren -- sehe ich das richtig?

Insgesamt glaube ich, dass sich das Hängenbleiben der Shell wohl auch einfacher beseitigen lässt.

Ich danke euch und wünsche eine gute Nacht.
Peter

Antworten