systemd-Unit -- PID erzeugen

  • Hallo,


    ich habe mich mal wieder an mein kleines Projekt gesetzt, das mit die Namen oder Telefonnummern der Anrufer (Namen auf dem FritzBox-Telefonbuch) vorlesen soll.

    Da das ganze auf einem PI mit Stretch läuft, habe ich eine Unit gezimmert, die auch funktioniert. Fast funktioniert.

    Was nicht funktioniert, ist das erstellen einer PID-Datei.


    Die Unis sieht so aus:


    Und funktioniert wunderbar.

    Entferne ich die # vor 'ExecstartPost' bricht der ganze Spaß ab.

    Meldung:


    In der Datei, welche die PID lesen und schreiben soll, steht:

    Shell-Script
    1. #!/bin/bash
    2. /bin/ps -ef|/bin/grep nummer_lesen.py|/bin/grep -v grep|/usr/bin/awk '{print $2}' > /tmp/rufnummer.pid
    3. #/bin/ps -ef|/bin/grep nummer_lesen.py|/bin/grep -v grep|/usr/bin/awk '{print $2}' > /var/run/rufnummer.pid

    Rufe ich dieses Script so auf, wie es dort steht, mit der ersten Zeile oder der zweiten Zeile. wird diese Datei geschrieben. Aber eben nicht aus der Unit.


    Der Verschlag im Internet mit

    Code
    1. /bin/sh -c 'umask 022; pgrep %Prozess%'

    funktioniert theoretisch. Nämlich nur, wenn der Aufruf

    Code
    1. /bin/sh -c 'umask 022; pgrep python'

    geschrieben wird, was unpraktisch ist, wenn man mehrere Python-Programm am laufen hat.

    Denn dann gibt es nicht nur eine PID.


    Hat jemand eine Idee, wie man die richtige PID bekommt und systemd nicht mault?

    Selber denken,
    wie kann man nur?

    Einmal editiert, zuletzt von Rasp-Berlin ()

  • Kling gut.

    Muss ich mal testen, ob es in der Unit auch so gut klingt ;-)


    Klingt nur gut, doch da ergibt sich:

    Code
    1. /bin/sh -c 'umask 022; /usr/bin/pgrep -f nummer_lesen.py'
    2. 1873
    3. 1891

    Ebenso beim suchen nach 'python', da eben nicht nach dem Programm, sondern nach dem Parameter gesucht wird, und das ist ja auch ein Parameter vom 'pgrep'


    Grrrrrrrrrrrrrrrrrrr

    Selber denken,
    wie kann man nur?

    Einmal editiert, zuletzt von Rasp-Berlin ()

  • Ebenso beim suchen nach 'python', da eben nicht nach dem Programm, sondern nach dem Parameter gesucht wird, und das ist ja auch ein Parameter vom 'pgrep'

    Hrm... pgrep sollte sich nicht selbst listen, kann ich hier auch nicht nachvollziehen.

    pgrep aus procps-2:3.3.12-3+deb9u1

    Das S in IOT steht für Sicherheit.

  • Hrm... pgrep sollte sich nicht selbst listen, kann ich hier auch nicht nachvollziehen.

    Macht er, wenn man so will, beim "-f" auch nicht. Dann wird aber nicht nach dem Namen des Programms gesucht, das den prozess offen hat, sondern nach einem Programm, das einen Parameter mit diesem Text hat. Und da ist eben (bei mir, beim aktuellen Stretch) pgrep dabei.

    pidof

    Hat das gleiche Problem wie "pgrep": Was machst du, wenn es mehrere Prozesse mit diesem Namen gibt. Wie findest du den gewünschten?

    Wenn du z.B. mittels 'grep' erst nach einem Aufrufparameter suchst, uns dann eben das ebenfalls enthaltene "grep" mittels "|grep -v grep" ausfilterst, musst nur nur noch die zweite Spalte filtern, eben mit "|awk '{print $2}' "

    Doch irgendwo bei diesem Filtern, oder auch nur schreiben der Datei, fällt das ganze auf die Füße, und der Prozess wird wegen eines Fehlers nicht gestartet.


    Das interessante ist, dass ich, mit den obigen Einstellungen, diesen Prozess killen kann, und systemd startet ihn wieder, den er steht ja auf "Restart allways"


    Eine PID ist also nicht dafür nötig, doch ich wollte es mit dieser ausprobieren.

    Jetzt ist eben meine Frage, wie man das machen kann, denn ich bin etwa ratlos.

    Selber denken,
    wie kann man nur?

  • Macht er, wenn man so will, beim "-f" auch nicht. Dann wird aber nicht nach dem Namen des Programms gesucht, das den prozess offen hat, sondern nach einem Programm, das einen Parameter mit diesem Text hat. Und da ist eben (bei mir, beim aktuellen Stretch) pgrep dabei

    Welche procps Version?

    Auf einem stretch-amd64 funktioniert das genau wie erwartet.

    ich starte testweise ein Python-Script (das einfach nur auf ENTER wartet) im Terminal:

    Code
    1. $ python3 keystroke.py
    2. Press Enter to continue...

    Und im anderen Terminal ("ps aux" zeigt wie das Script "keystroke.py" aufgerufen wurde) und

    "pgrep -f keystroke" ergibt lediglich die erwartete PID

    Code
    1. llutz@saturn:~$ ps aux
    2. ...llutz 9931 1.0 0.0 29068 8312 pts/3 S+ 11:17 0:00 python3 keystroke.py
    3. llutz 9932 0.0 0.0 40092 3544 pts/0 R+ 11:17 0:00 ps aux
    4. llutz@saturn:~$ pgrep -f keystroke
    5. 9931
    6. llutz@saturn:~$ type pgrep
    7. pgrep ist /usr/bin/pgrep
    8. llutz@saturn:~$

    Das S in IOT steht für Sicherheit.

  • Dann wird aber nicht nach dem Namen des Programms gesucht, das den prozess offen hat, sondern nach einem Programm, das einen Parameter mit diesem Text hat. Und da ist eben (bei mir, beim aktuellen Stretch) pgrep dabei.

    Kann ich hier nicht nachvollziehen.

    Jetzt ist eben meine Frage, wie man das machen kann, denn ich bin etwa ratlos.

    Ich würde sagen: Im Skript selbst:

    Code
    1. import os
    2. with open("/var/run/rufnummer.pid","w") as f:
    3. f.write(os.getpid())

    oder so ähnlich.

  • stretch-amd64

    Hmmm, ich glaube, wir reden hier von einem PI mit Raspian. Da ist der Einwand zum x86-Debian irgendwie passend.

    Ich würde sagen: Im Skript selbst:

    Warum sollte ich das im Script machen? Diesem ist die PID vollkommen egal. Interessant wäre sie z.B. für eine Prozessüberwachung, doch die kann nicht aus dem Script selber kommen.

    Kann ich hier nicht nachvollziehen.

    Wenn ich bei meinem PI "ps -ef |pgrep -f nummer_auslesen" aufrufe, bekomme ich zwei PID ausgegeben. Rufe ich dagegen "ps -ef |pgrep python" auf, kommt nur eine, und zwar die des laufenden Python-Interpreters, des mein Script laufen lässt.

    Die zweite kann man nicht mehr nachvollziehen, da der "pgrep"-Prozess zu Ende ist.


    Startet doch einfach mal drei Python Prozesse, zwei drehen Däumchen, und ihr wollt die PID des dritten haben.

    Selber denken,
    wie kann man nur?

  • Wenn du z.B. mittels 'grep' erst nach einem Aufrufparameter suchst, uns dann eben das ebenfalls enthaltene "grep" mittels "|grep -v grep" ausfilterst, ...

    grep muss man nicht ausfiltern. Z. B.:

    Code
    1. :~ $ ps aux | grep -i [w]pa
    2. root 377 0.0 0.2 5208 2668 ? Ss 10:04 0:00 /sbin/wpa_supplicant -B -M -qq -c/etc/wpa_supplicant/wpa_supplicant-nl80211-wlan0.conf -Dnl80211 -iwlan*

    im Vergleich zu:

    Code
    1. :~ $ ps aux | grep -i wpa
    2. root 377 0.0 0.2 5208 2668 ? Ss 10:04 0:00 /sbin/wpa_supplicant -B -M -qq -c/etc/wpa_supplicant/wpa_supplicant-nl80211-wlan0.conf -Dnl80211 -iwlan*
    3. pi 8407 0.0 0.2 6140 1884 pts/0 S+ 13:10 0:00 grep --color=auto -i wpa
  • Wenn ich bei meinem PI "ps -ef |pgrep -f nummer_auslesen" aufrufe,

    Was soll denn das "ps -ef" da? Damit pipest Du den output des ps-Befehls nach pgrep. Keine Ahnung, was das damit macht, brauchen tut's das auf jeden Fall nicht. Der komplette Aufruf wäre also "pgrep -f nummer_auslesen", ohne "ps -ef|" davor.

    Warum sollte ich das im Script machen?

    Weil's am einfachsten und m.W. auch gängige Praxis ist.

    Diesem ist die PID vollkommen egal.

    Schon klar, aber trotzdem darf es nett sein und denen, die auf es aufpassen sollen, mitteilen, wo sie es finden. ;)

    Interessant wäre sie z.B. für eine Prozessüberwachung, doch die kann nicht aus dem Script selber kommen.

    Eben, die macht systemd. Dafür braucht es aber Zugriff auf die PID, den Du ihm auf diese Art am einfachsten zur Verfügung stellst.

  • Zitat

    Die PPID kann man z. B. mit ps feststellen (wenn man die PID kennt)

    Hat jemand nach dieser gefragt? Ich nicht

    Selber denken,
    wie kann man nur?

    Einmal editiert, zuletzt von Rasp-Berlin ()