Mein Versuch mit ein Perl-Skript mit init.d automatisch zu starten droht zu scheitern.
Starte ich das Perl-Skript von der Befehlszeile mit einem '&' läuft alles einwandfrei:
fhem@FHEMDEV:~$ /opt/fhem/www/fing/fingService.pl &
[1] 5039
fhem@FHEMDEV:~$ pgrep -f fingService.pl
5039
fhem@FHEMDEV:~$ pidof fingService.pl
fhem@FHEMDEV:~$ pidof fingService
fhem@FHEMDEV:~$
top - 17:50:17 up 38 min, 3 users, load average: 0,05, 0,03, 0,01
Tasks: 142 gesamt, 1 laufend, 141 schlafend, 0 gestoppt, 0 Zombie
%CPU(s): 0,2 be, 0,3 sy, 0,0 ni, 99,5 un, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
KiB Spch : 2041468 gesamt, 1511072 frei, 224476 belegt, 305920 Puff/Cache
KiB Swap: 2097148 gesamt, 2097148 frei, 0 belegt. 1662724 verfü Spch
PID USER PR NI VIRT RES SHR S %CPU %MEM ZEIT+ BEFEHL
2234 root 20 0 0 0 0 S 0,0 0,0 0:00.03 kworker/u6+
2235 root 20 0 101448 6856 5872 S 0,0 0,3 0:00.01 sshd
2285 fhem 20 0 101448 3592 2612 S 0,0 0,2 0:00.09 sshd
2286 fhem 20 0 24288 5248 3388 S 0,0 0,3 0:00.03 bash
2292 fhem 20 0 48656 14348 4640 S 0,0 0,7 0:00.08 fingServic+
2293 root 20 0 60760 4176 3680 S 0,0 0,2 0:00.00 sudo
2294 root 20 0 4496 708 632 S 0,0 0,0 0:00.00 fing
fhem@FHEMDEV:~$ pidof fing
fhem@FHEMDEV:~$ pgrep -f fingService
2292
fhem@FHEMDEV:~$ pgrep -f fing
2292
2293
2294
2295
Da es vom Verhalten ähnlich, wie homebridge im Hintergrund arbeiten soll, habe ich das zugehörige init.d Skript als Muster für meine Versuche genommen. Das erste Problem ergab sich bereits in der Code-Zeile PID = `pidof fingService`. Ich habe es auch im Terminal nicht hinbekommen mit pidof die PID zu ermitteln (s.o.). obwohl pgrep die korrekt PID anzeigt, wenn es im Terminal gestartet wurde. Deswegen habe ich 'pidof' durch pgrep ersetzt, in der Hoffnung das der weitere Code dann korrekt funktioniert, leider vergebens. Es wird scheinbar willkürlich eine PID ermittelt, was dazu führt, dass der eigentliche start-Befehl nicht ausgeführt wird.
1. Wie stelle ich sicher, dass die korrekte PID ermittelt wird?
2. Wie muss der korrekte Startbefehl aussehen (die Umleitungen für homebridge sind meiner Ansicht nach nicht notwendig)?
Vielen Dank
Gernot
Nicht korrekt funktionierender /etc/init.d/fingService
#!/bin/sh
### BEGIN INIT INFO
# Provides: fingService
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $syslog $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time for fingService
# Description: Enable service provided by daemon.
### END INIT INFO
export PATH=$PATH:/usr/local/bin
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules
PID=`pgrep -f fingService`
fingUser="fhem"
fhemHost=127.0.0.1 #FHEM Server (Masterinstanz)
fhemHostTelnetPort=7072 #TelnetPort der FHEM Instanz
fhemDefine="nc_init"
case "$1" in
start)
if ps -p $PID > /dev/null 2>&1; then
echo "fingService is already running"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info fingService is already running"
else
#su - $fingUser -c "/opt/fhem/www/fing/fingService.pl > /dev/null 2>&1 &"
su - $fingUser -c "/opt/fhem/www/fing/fingService.pl &"
echo "fingService starting"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info fingService starting"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine on"
sleep 2
$0 status
fi
;;
stop)
if ! ps -p $PID > /dev/null 2>&1; then
echo "fingService is not running"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info fingService is not running"
else
kill $PID
echo "fingSercive stopping"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info fingService stopping"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine off"
sleep 2
$0 status
fi
;;
restart)
if ! ps -p $PID > /dev/null 2>&1; then
$0 start
else
$0 stop
$0 start
fi
;;
status)
if ps -p $PID > /dev/null 2>&1; then
echo "fingService is running PID $PID"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info fingService running as PID $PID"
else
echo "fingService is not running"
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info fingService is not running"
fi
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
Versuche mal pidof mit "-x" zu benutzen.
oder mit -s ;)
Ein bash skript kann seine eigene pid übrigens einfach über $$ ermitteln.
Gib mal auf der Konsole "echo $$" ein und staune.
Wie man ein perl Skript per init.d startet, kannst Du Dir doch am mitgeliefereten init-Skript von FHEM anschauen, da wird genau das gemacht.
Wow, super schnell. Danke betateilchen und Stromer-12.
fhem@FHEMDEV:~$ pgrep -f fingService
2292
fhem@FHEMDEV:~$ pidof -s fingServie
fhem@FHEMDEV:~$ pidof -x fingServie
fhem@FHEMDEV:~$ echo $$
2985
fhem@FHEMDEV:~$
diese Parameter habe ich sicherheitshalber auf eure Empfehlung hin nocheinmal versucht. Leider ohne Erfolg (s.o.). Der echo $$ Befehl funktioniert, aber wie kann ich den im init.d Skript verwenden?
Wenn ich das richtig verstehe, müsste er im eigentlichen Perl Skript verwendet werden und über eine Datei an das init.d weitergeben werden, oder. gibt es eine elegantere Lösung.
Warum gibt pidof keinen Wert aus, das verstehe ich nicht?
Danke,
Gernot
Zitat von: supernova1963 am 03 Juni 2017, 18:52:06
Wow, super schnell. Danke betateilchen und Stromer-12.
fhem@FHEMDEV:~$ pgrep -f fingService
2292
fhem@FHEMDEV:~$ pidof -s fingServie
fhem@FHEMDEV:~$ pidof -x fingServie
fhem@FHEMDEV:~$
Warum gibt pidof keinen Wert aus, das verstehe ich nicht?
Dein gesuchtes Programm heißt ja auch anders.
An-für-sich heißt das gestartete Programm /opt/fhem/www/fing/fingService.pl, und es wird von pgrep ja auch gefunden.?
Oder hast du einen Fehler entdeckt?
Danke,
Gernot
Sorry, du hast recht das Programm heißt Perl.
Wenn ich das eingebe kommt die PID, aber leider auch noch einige andere
fhem@FHEMDEV:~$ pidof perl
2292 1298 1287
fhem@FHEMDEV:~$
Du hast bei den pidof das c im Programmnamen vergessen.
Danke, ich hab's korrigiert, aber das Ergebnis bleibt gleich:
fhem@FHEMDEV:~$ pidof -s fingService
fhem@FHEMDEV:~$ pidof -x fingService
fhem@FHEMDEV:~$
Zitat von: supernova1963 am 03 Juni 2017, 19:09:01
Wenn ich das eingebe kommt die PID, aber leider auch noch einige andere
fhem@FHEMDEV:~$ pidof perl
2292 1298 1287
fhem@FHEMDEV:~$
probier mal
ps xf | grep 'perl fhem.pl' | grep -v '\_' | cut -d ' ' -f 1
ich kapiere immer noch nicht, was Du eigentlich als Ergebnis haben willst und wozu Du das brauchst.
Hallo SabineT,
Danke für deinen Tip. Ich hab's versucht:
fhem@FHEMDEV:~$ ps xf | grep 'perl fhem.pl' | grep -v '\_' | cut -d ' ' -f 1
fhem@FHEMDEV:~$ ps xf
PID TTY STAT TIME COMMAND
4779 ? S 0:00 sshd: fhem@pts/3
4780 pts/3 Ss 0:00 \_ -bash
4792 pts/3 R+ 0:00 \_ ps xf
2285 ? S 0:00 sshd: fhem@pts/2
2286 pts/2 Ss+ 0:00 \_ -bash
2292 pts/2 S 0:00 \_ /usr/bin/perl -w /opt/fhem/www/fing/fingServic 1494 ? S 0:00 sshd: fhem@pts/1
1495 pts/1 Ss+ 0:00 \_ -bash
1410 ? S 0:00 sshd: fhem@pts/0
1411 pts/0 Ss+ 0:00 \_ -bash
1334 ? Ss 0:00 /lib/systemd/systemd --user
1335 ? S 0:00 \_ (sd-pam)
1287 ? S 0:04 perl fhem.pl fhem.cfg
fhem@FHEMDEV:~$ ps xf | grep 'perl fhem.pl'
4795 pts/3 S+ 0:00 \_ grep perl fhem.pl
1287 ? S 0:04 perl fhem.pl fhem.cfg
fhem@FHEMDEV:~$ ps xf | grep 'perl fhem.pl' | grep -v '\_'
1287 ? S 0:04 perl fhem.pl fhem.cfg
fhem@FHEMDEV:~$ ps xf | grep 'perl fhem.pl' | grep -v '\_' | cut -d ' ' -f 1
fhem@FHEMDEV:~$
Wenn ich deine grep Funktionen richtig verstehe geht das in Richtung PID von fhem. Ich benötige jedoch die PID 2292 .... fingService.
Wenn's keine einfachere Möglichkeit gibt, versuche ich deinen Vorschlag zu verstehen und umzuschreiben.
Alternativ wäre auch ein Start in myUtils. Da schreckt mich aber derzeit noch die blocking bzw. subprocess Thematik ab.
Gernot
@betateilchen: mit dem Perl Skript lese die stout Ausgaben von dem Programm overlook fing aus und lege dummies in Fhem an
Hier der Code:
fhem@FHEMDEV:~$ cat /opt/fhem/www/fing/fingService.pl
#!/usr/bin/perl -w
package main;
use strict;
use warnings;
use POSIX;
use LWP::Simple;
use v5.18.2;
use Net::Telnet ();
#use Blocking;
#use XML::LibXML;
my ($fingbefehl) = @ARGV;
my @array;
my $devicename='';
my $nr = 0;
my $FHEMBefehl = '';
my $regex = qr/:/p;
my $subst = '_';
my $telnet = new Net::Telnet ( Timeout=>10, Errmode=>'die');
$telnet->open(Port=>'7072');
#$telnet->waitfor('/Password:/');
#$telnet->print('97895');
$FHEMBefehl = 'set group=NetClients down';
$telnet->print($FHEMBefehl);
open FINGDUMP, "-|", "sudo fing -n 192.168.1.105/24 -o log,csv,console";
while (<FINGDUMP>) {
my ($Uhrzeit,$Action) = split(/>/);
my ($Zeitpunkt,$Status,$IP,$Name,$Hostname,$MAC,$Vendor) = split(/;/);
if (defined($Action)) {
my ($Netzkennung,$Netz)=split(/Discovery on:/,$Action);
my ($Fortschrittkennung,$Fortschritt)=split(/Discovery progress /,$Action);
if (defined($Netz)) {
$Netz =~ s/ //;
}
elsif (defined($Fortschritt)) {
$Fortschritt =~ s/\%//;
}
else {
}
}
elsif (defined($MAC)) {
$nr = substr($IP,rindex($IP,'.')+1);
$nr = substr("000".$nr, -3, 3);
$devicename = $MAC;
$devicename ='nc_'.$devicename =~ s/:/_/rg;
$FHEMBefehl = 'defmod '.$devicename.' dummy';
$telnet->print($FHEMBefehl);
$FHEMBefehl = 'setreading '.$devicename.' IP '.$IP;
$telnet->print($FHEMBefehl);
$FHEMBefehl = 'setreading '.$devicename.' MAC '.$MAC;
$telnet->print($FHEMBefehl);
$FHEMBefehl = 'setreading '.$devicename.' state '.$Status;
$telnet->print($FHEMBefehl);
$FHEMBefehl = 'setreading '.$devicename.' NR '.$nr;
$telnet->print($FHEMBefehl);
$FHEMBefehl = 'attr '.$devicename.' sortby '.$nr;
$telnet->print($FHEMBefehl);
if (length($Name)>2) {
$FHEMBefehl = 'attr '.$devicename.' alias '.$Name;
$telnet->print($FHEMBefehl);
}
if (length($Hostname)>2) {
$FHEMBefehl = 'setreading '.$devicename.' HOSTNAME '.$Hostname;}
else {
$FHEMBefehl = 'setreading '.$devicename.' HOSTNAME n/a';
}
$telnet->print($FHEMBefehl);
if (length($Vendor)>2) {
$FHEMBefehl = 'setreading '.$devicename.' VENDOR '.$Vendor;}
else {
$FHEMBefehl = 'setreading '.$devicename.' VENDOR n/a'}
$telnet->print($FHEMBefehl);
#Attribut group setzen, damit die NetClient Dummy's in einem Raum zusammengefaßt angelistet werrden
$FHEMBefehl = 'attr '.$devicename.' group NetClients';
$telnet->print($FHEMBefehl);
# Attribut room setzen, damit die NetClient Dummy's einem Raum zugeordnet werden
$FHEMBefehl = 'attr '.$devicename.' room Netz';
$telnet->print($FHEMBefehl);
$FHEMBefehl = 'setreading nc_init nc '.$devicename;
$telnet->print($FHEMBefehl);
$FHEMBefehl = 'setreading nc_init ncAnlageStandard on';
$telnet->print($FHEMBefehl);
$telnet->print('save');
}
else {
printf "";
}
}
close FINGDUMP;
$telnet->print('exit');
fhem@FHEMDEV:~$
Dann müsste so gehen:
ps xf | grep 'fingServic' | cut -d ' ' -f 1
fingServic darf halt dann nur 1x laufen. Ansonsten müsstest du das grep entsprechend erweitern. Also im Extremfall
ps xf | grep '\_ /usr/bin/perl -w /opt/fhem/www/fing/fingServic' | cut -d ' ' -f 1
Im Prinzip rufe ich erst mal ps xf auf, der output wird dann aber mit dem | an das grep als input übergeben. Das grep filtert dann einfach genau die Zeile raus, die dein gewünschtes Programm enthält. Und das cut schneidet dann das erste Feld der Zeile heraus, also die PID.
Super, das ist fast perfekt. Diese PID Suche soll u.A. verhindern, dass es doppelt ausgeführt wird.
Hast du noch eine Idee, wie man so genial ausschließen kann, dass die PID von grep mit dem Suchbegriff angezeigt wird?
Hinweis: der cut muss bei dem 2. Leerzeichen erfolgen:
fhem@FHEMDEV:~$ ps xf | grep 'fingServic' | cut -d ' ' -f 2
5842
2292
Vielen, vielen Dank,
Gernot
Dann mach
ps xf | grep 'fingServic' | grep -v grep | cut -d ' ' -f 2
Das 'grep -v grep' lässt alles durch, was nicht grep in der Zeile stehen hat
Einfach genial, so funktioniert's
fhem@FHEMDEV:~$ ps xf | grep 'fingServic' | grep -v grep | cut -d ' ' -f 2
2292
fhem@FHEMDEV:~$
Danke, ich selten in so kurzer Zeit soviel gelernt,
Gernot
Die Zeile sollte kürzer auch so gehen:
ps fx | grep [f]ingServic | cut -c-5
bei 5stelliger PID ist es mit der anderen Version wieder -f1
Danke für den Hinweis, Stromer-12.
Ich probiere es gleich morgen aus,
Gernot