Autor Thema: execute shell command in nonblocking call.  (Gelesen 369 mal)

Offline charlie71

  • Developer
  • Full Member
  • ****
  • Beiträge: 307
execute shell command in nonblocking call.
« am: 05 Januar 2018, 12:15:26 »
Hallo Leute,
ich habe folgendes Problem, in einem non-blocking call möchte ich ein shell command aufrufen.
Leider funktioniert das nicht, irgend wie scheint das alles im shell execute command hängen zu bleiben. Ich habe alles bis auf den quote execute command auskommentiert, da scheint das Modul zu funktionieren, es wird die finishFn sauber aufgerufen.

Wenn der quote execute command aufgerufen wird, geht leider nichts mehr. Als shell command habe ich whoami gewählt.

Vielen Dank für eure Hilfe
Charlie71

Hier mein Modul code
##############################################
# $Id: myTempNB.pm  2018-01-05  charlie71
#
package main;

use strict;
use warnings;
use Blocking;
use Time::HiRes qw(gettimeofday);

sub myTempNB_Initialize($) {
my ($hash) = @_;
$hash->{DefFn}         = "myTempNB_Define";
$hash->{UndefFn}       = "myTempNB_Undef";

$hash->{AttrList}      = "timeout " . $readingFnAttributes;
 }
#####################################
sub myTempNB_Define($$) {
my ( $hash, $def ) = @_;

my @a = split( "[ \t][ \t]*", $def );

return
  "Usage: define <name> myTempNB <address> [<intervall>]"
  if ( @a < 3 || @a > 4 );

my $name  = $a[0];
my $address   = $a[2];
my $inter = 300;

if ( int(@a) == 4 ) {
$inter = $a[3];
if ( $inter < 5 ) {
return
  "interval too small, please use something > 5, default is 300";
}
}

$hash->{name}     = $name;
$hash->{address}  = $address;
$hash->{interval} = $inter;

#Aufraemen
delete( $hash->{helper}{RUNNING_PID} );
RemoveInternalTimer($hash);

# my $res = myTempNB_bcReadData($hash->{NAME} . "|"  . $hash->{address});
# Log3 $hash, 3, "[$name] get Value: $res";

# initial request after 2 secs, there timer is set to interval for further update
InternalTimer( gettimeofday() + 2, "myTempNB_GetUpdate", $hash, 0 );

return undef;
}
#####################################
sub myTempNB_GetUpdate($) {
my ($hash) = @_;
my $name = $hash->{name};
my $timeout = $hash->{interval} - 2;

if ( defined( $main::attr{$name}{timeout} ) ) {
           $timeout = $main::attr{$name}{timeout};
        }


InternalTimer( gettimeofday() + $hash->{interval},
"myTempNB_GetUpdate", $hash, 1 );

Log3( $name, 3, "myTempNB: GetUpdate called ... timeout = $timeout" );


    my $arg        = $hash->{NAME} . "|" . $hash->{address};
    my $blockingFn = "myTempNB_bcReadData";
    my $finishFn   = "myTempNB_bcDone";
    my $abortFn    = "myTempNB_Abort";

   #ja ich weiss die nächsten 2 Zeilen machen wenig sinn, aber ich teste nur
   BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));
   delete( $hash->{helper}{RUNNING_PID} );
   
   if (!(exists($hash->{helper}{RUNNING_PID}))) {
      $hash->{helper}{RUNNING_PID} =
         BlockingCall($blockingFn, $arg, $finishFn, $timeout, $abortFn, $hash);
  } else {
    Log3 $hash, 3, "[$name] Blocking Call running no new started";
  }
}

#####################################
sub myTempNB_bcReadData($) {

my ($string) = @_;
my ( $name, $address ) = split( "\\|", $string );
my $val;

my $err_log = "";

my $cmd ="whoami";#nur zum Testen
my $res = 0;

eval {
local $SIG{__DIE__} = sub {
my ($s) = @_;
$err_log = $s;
$res = -1;
};
$val = qx($cmd);
};

my $return;

if ($res == 0) {
$return = "$name|0|$val";
} else {
$return = "$name|1|$err_log";
}
return $return;
}
#####################################

sub myTempNB_bcDone($) {
my ($string) = @_;
return unless ( defined($string) );

my @a    = split("\\|", $string);
my $name = $a[0];
my $hash = $defs{$name};

Log3( $name, 3, "myTempNB: bcDone... $string" );

delete( $hash->{helper}{RUNNING_PID} );


if ( @a < 3 || $a[1] != 1 ) {

#error situation
$hash->{STATE} = "Error";
Log3( $name, 3, $a[2] );
return;
}
my $whoami    = $a[2];
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "whoami",         $whoami );
readingsEndUpdate( $hash, 1 );

$hash->{STATE} = "OK";
}

#####################################

sub myTempNB_Abort($) {
my ($hash) = @_;

delete( $hash->{helper}{RUNNING_PID} );

Log3( $hash->{NAME}, 4,
"BlockingCall for " . $hash->{NAME} . " was aborted" );
}

#####################################
sub myTempNB_Undef($) {
my $hash = shift;

RemoveInternalTimer($hash);

BlockingKill( $hash->{helper}{RUNNING_PID} )
  if ( defined( $hash->{helper}{RUNNING_PID} ) );

delete( $modules{myTempNB}{defptr} );

return undef;
}



1;


hier mein Logfile auszug:
2018.01.05 12:11:03.038 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:11:13.042 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:11:23.044 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:11:33.082 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:11:43.084 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:11:53.087 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:12:03.089 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:12:13.092 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:12:23.129 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:12:33.132 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:12:43.211 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:12:53.213 3: myTempNB: GetUpdate called ... timeout = 8
2018.01.05 12:13:03.216 3: myTempNB: GetUpdate called ... timeout = 8