FHEM Forum

FHEM - Entwicklung => FHEM Development => Thema gestartet von: Wuppi68 am 28 Oktober 2017, 14:13:26

Titel: Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: Wuppi68 am 28 Oktober 2017, 14:13:26
Hallo Zusammen,

in einem Modul (Trädfri) steht folgender Code:
my $coapClientCMD = "timeout 5s coap-client -u Client_identity -k $gwSecret -v 1 -m $method coaps://$gwAddress:5684/$path";

if(%data){
my $jsonData = JSON->new->utf8->encode(\%data);
$coapClientCMD = "echo '$jsonData' | " . $coapClientCMD . " -f -";
}

$coapClientCMD = $coapClientCMD . " 2>/dev/null";

my $return = `$coapClientCMD`;



hat für einen solchen Aufruf schon jemand eine Lösung im Ärmel?

timeout killed nach 5 Sekunden automatisch das aufgerufnene Programm
coap-client bleibt bei diesen Parametern im "tty Input Modus" wartet also auf weitere Eingaben

ergo FHEM ist für 5 Sekunden total blockiert und "nichts" geht mehr

Gruß und Dank

Ralf
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: rudolfkoenig am 28 Oktober 2017, 16:16:37
Falls du an das return Wert interessiert bist: BackendCall.

Oder open(fd, "myCommand|"), fd ins %selectlist einhaengen, und Behandlung im ReadFn. Funktioniert vermutlich nicht unter windows, da pipe da nicht select faehig ist.
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: Wuppi68 am 28 Oktober 2017, 23:05:28
Danke Rudi
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 10 November 2017, 15:39:01
Ich suche auch gerade eine Lösung um an den return Wert zu kommen.

Mache ich:
my $ret = qx(which ssh);
chomp $ret;

bekomme ich den Pfad zu ssh.

Mit:
my $ret = qx(killall myapp);
Kommt trotz nicht vorhandener Berechtigungen nicht der Fehler zurück der auf der Konsole ausgeworfen wird.

Ich komme hier nicht weiter, benötige aber eben diese Fehlermeldung.

Was ist mit BackendCall gemeint? Habe dazu nichts finden können.

Danke.

Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: Wuppi68 am 10 November 2017, 16:14:25
Zitat von: DeeSPe am 10 November 2017, 15:39:01
Ich suche auch gerade eine Lösung um an den return Wert zu kommen.

Mache ich:
my $ret = qx(which ssh);
chomp $ret;

bekomme ich den Pfad zu ssh.

Mit:
my $ret = qx(killall myapp);
Kommt trotz nicht vorhandener Berechtigungen nicht der Fehler zurück der auf der Konsole ausgeworfen wird.

Ich komme hier nicht weiter, benötige aber eben diese Fehlermeldung.

Was ist mit BackendCall gemeint? Habe dazu nichts finden können.

Danke.

Gruß
Dan

Wenn Du nicht den Return Value brauchst kannst Du auch "2>$1" die Errorausgabe umleiten ...
oder Du connectest Dich auf STDOUT(1) und STDERR(2) und hast dann beide Ausgaben getrennt in den Fildeskriptorren
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 10 November 2017, 16:22:02
Zitat von: Wuppi68 am 10 November 2017, 16:14:25
Wenn Du nicht den Return Value brauchst kannst Du auch "2>$1" die Errorausgabe umleiten ...
oder Du connectest Dich auf STDOUT(1) und STDERR(2) und hast dann beide Ausgaben getrennt in den Fildeskriptorren

Es geht mir genau um den Rückgabewert (im Fehlerfall), damit ich diesen dem User mitteilen kann.

Wie connecte ich denn auf STDOUT(1) und STDERR(2)?

Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: Wuppi68 am 10 November 2017, 16:25:39
Zitat von: DeeSPe am 10 November 2017, 16:22:02
Es geht mir genau um den Rückgabewert (im Fehlerfall), damit ich diesen dem User mitteilen kann.

Wie connecte ich denn auf STDOUT(1) und STDERR(2)?

Gruß
Dan

schau mal hier http://www.perlmonks.org/?node=How%20can%20I%20capture%20STDERR%20from%20an%20external%20command%3F

habe ich auch noch nicht gemacht ;-)
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 10 November 2017, 16:56:37
Zitat von: Wuppi68 am 10 November 2017, 16:25:39
schau mal hier http://www.perlmonks.org/?node=How%20can%20I%20capture%20STDERR%20from%20an%20external%20command%3F

Danke für den Link.
Habe jetzt mal einige Beispiele von dort probiert, bekomme aber nach wie vor nicht die Fehlermeldung ausgegeben.
Stelle ich mich denn so an?

Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: CoolTux am 10 November 2017, 17:57:58
2>&1

Nicht $1

Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 10 November 2017, 21:27:36
Zitat von: CoolTux am 10 November 2017, 17:57:58
2>&1

Nicht $1

Ich habe kopiert! Da schleicht sich kein $ ein!  :P
Komme leider nach wie vor nicht an die Fehlerausgabe. :o

Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 10 November 2017, 23:25:25
Ich glaub jetzt hab ich's.
Manchmal hat man wirklich Tomaten auf den Augen. :P

Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: CoolTux am 11 November 2017, 07:22:49
Und was war es, erzähl Mal bitte.
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 11 November 2017, 10:21:26
Zitat von: CoolTux am 11 November 2017, 07:22:49
Und was war es, erzähl Mal bitte.

Das ist mir peinlich! ::)

Um es der non-blocking Funktion zuzuführen habe ich das CMD in base64 kodiert.
In meiner Testfunktion hatte ich dann vergessen das encode zu entfernen.... :-[

Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: CoolTux am 11 November 2017, 10:42:20
 ;D
Verstehe. Darauf nun ein Bierschen und ein schönes Wochenende gewünscht


Grüße
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 12 November 2017, 10:21:05
Irgendwie hakt es immer noch.

Rufe ich mein Shell-CMD sofort im set auf bekomme ich die Fehlermeldung zurück.
Mache ich das Selbe in einem BlockingCall bekomme ich die Fehlermeldung nicht zurück denn die FinishFn wird offensichtlich nicht aufgerufen.
Auch die AbortFn wird nicht aufgerufen.

Ohne BlockingCall:
my $com = $sudo."killall $bin 2>&1";
my @error = qx($com);
Debug "Error: ".join "~~~",@error;

ergibt das bei fehlenden Berechtigungen:
Error: ~~~Wir gehen davon aus, dass der lokale Systemadministrator Ihnen die ~~~Regeln erklärt hat. Normalerweise läuft es auf drei Regeln hinaus: ~~~ ~~~ #1) Resprektieren Sie die Privatsphäre anderer. ~~~ #2) Denken Sie nach bevor Sie tippen. ~~~ #3) Mit großer Macht kommt große Verantwortung. ~~~ ~~~sudo: Kein TTY vorhanden und kein »askpass«-Programm angegeben

Genau der selbe Code im BlockingCall kommt nie zurück.

Kann mich bitte jemand erleuchten?

Danke.

Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: CoolTux am 12 November 2017, 10:32:47
Zu meist befindet sich dann ein Zeilenumbruch in der Rückgabe. Da die Rückgabe über telnet geht darf kein Zeilenumbruch drin sein. Entweder base64 codieren oder JSON encodieren und dann in der finishFn decodieren.
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 12 November 2017, 13:53:59
Mit ein Wenig RegEx Zauberei konnte ich das Problem nun lösen.
Problematisch waren scheinbar tatsächlich noch enthaltene Tabulatoren.

Merkwürdig ist nur dass die Fehlerrückgabe als base64 nicht funktioniert, das ein Weile gedauert bis das aufgefallen ist.

Das geht:
$err .= join " ",@ret;
return "$name|$err";


Das geht nicht:
$err .= encode_base64(join " ",@ret);
return "$name|$err";

natürlich mit entsprechendem decode in der FinishFn:

my ($string) = @_;
my @a = split /\|/,$string;
my $name = $a[0];
my $error = decode_base64($a[1]);


Gruß
Dan
Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DS_Starter am 25 November 2017, 20:03:44
Hi Dan,

ich kodiere in diesem Fall immer mit einem zweiten (leeren) Stringargumnt am Ende:


$err = encode_base64($string,"");


Das zweite Argument verhindert dass der verschlüsselte String in Zeilen umgebrochen wird, was ja in unserem Anwendungsfall nicht sein darf.

Ich hatte das mal gefunden, z.B. hier (beware of the newline at the end of the encode_base64-encoded strings):
http://www.perlmonks.org/?node_id=660474 

oder auch in der CPAN-Doku:

http://search.cpan.org/~gaas/MIME-Base64-Perl-1.00/lib/MIME/Base64/Perl.pm

Seitdem habe ich mit soetwas keinen Stress mehr.

Grüße
Heiko




Titel: Antw:Hilfe bei Shellaufruf in einem Modul (umstellen auf Non Blocking)
Beitrag von: DeeSPe am 25 November 2017, 20:11:46
Zitat von: DS_Starter am 25 November 2017, 20:03:44
Hi Dan,

ich kodiere in diesem Fall immer mit einem zweiten (leeren) Stringargumnt am Ende:


$err = encode_base64($string,"");


Das zweite Argument verhindert dass der verschlüsselte String in Zeilen umgebrochen wird, was ja in unserem Anwendungsfall nicht sein darf.

Ich hatte das mal gefunden, z.B. hier (beware of the newline at the end of the encode_base64-encoded strings):
http://www.perlmonks.org/?node_id=660474 

oder auch in der CPAN-Doku:

http://search.cpan.org/~gaas/MIME-Base64-Perl-1.00/lib/MIME/Base64/Perl.pm

Seitdem habe ich mit soetwas keinen Stress mehr.

Grüße
Heiko

Klasse Hinweis Heiko!
Diese Info hatte mir gefehlt.
Jetzt klappt es auch mit en/decode.

Gruß
Dan