Wie festhängende Skripte automatisch beenden?

Hallo Zusammen,

nachdem ich vor einiger Zeit leider festgestellt habe, dass IPS bzw. PHP kein Zeitlimit für Skripte mehr besteht, bringt mir das ab und an „Ärger“:

Mein IPS wird jede Nacht um 3:00 beendet und der Ordner wird als Zip weggesichert. Danach wird IPS wieder gestartet. (Linux, Bullseye)
Leider passiert aber ab und an (sehr selten) folgendes: Ein Skript hängt sich auf bzw. läuft nicht zu Ende und IPS fährt dann auch nicht zu Ende runter.

Dann muss ich den Host händisch per SSH rebooten.
Wie kann ich hängende Skripte detektieren und nach eine bestimmten Dauer beenden? Oder alternativ, wie kann ich bestimmte Skripte nach einer gewissen Zeit zwangsbeenden?
(Eins davon ist z.B. die Abfrage von Daten aus der VW WeConnect-Cloud, das führt ab und an zu o.g. Problem).

Gruß,
Maeffjus

Gar nicht. Zwangsbeenden ist nicht möglich, außer durch Killen des Dienstes. Das Detektieren geht, indem du die laufenden Threads bzgl. Laufzeit auswertest. Das ist natürlich nur ein Indiz (es kann ja durchaus Skripte geben, die erst nach langer Zeit fertig werden).

1 „Gefällt mir“

überhaupt nicht :wink: , dafür musst du Symcon neu starten

1 „Gefällt mir“

Das Problem ist, es hängt z.B. der Datenabruf von meinem Arteon - dann kann ich das ggf. sogar sehen und genau garnichts machen?
Denn - wenn IPS um 3:00 hängt, dann macht die Heizung um 7:00 auch kein Warmwasser :wink:

Hat vielleicht jemand denn konkret am Skript ne Idee:

<?php
 $output = exec('sudo -i -u dietpi /home/dietpi/.local/bin/weconnect-cli --username GEHEIM get /vehicles/WVWZZZ3HZNE506254/domains/charging/batteryStatus/currentSOC_pct');
 SetValueInteger(12994,$output);

$output2 = exec('sudo -i -u dietpi /home/dietpi/.local/bin/weconnect-cli --username GEHEIM get /vehicles/WVWZZZ3HZNE506254/domains/measurements/rangeStatus/electricRange');
 SetValueInteger(21047,$output2);

$output3 = exec('sudo -i -u dietpi /home/dietpi/.local/bin/weconnect-cli --username GEHEIM get /vehicles/WVWZZZ3HZNE506254/domains/charging/chargingStatus/remainingChargingTimeToComplete_min');
 SetValueInteger(39972,$output3);

$output4 = exec('sudo -i -u dietpi /home/dietpi/.local/bin/weconnect-cli --username GEHEIM get /vehicles/WVWZZZ3HZNE506254/domains/climatisation/climatisationStatus/climatisationState');
 If ($output4 == "off") {
 SetValueInteger(35908,0);
 }
 elseif ($output4 == "cooling") {
SetValueInteger(35908,1);
 }
 elseif ($output4 == "heating") {
SetValueInteger(35908,2);
 }

$date=strtotime(date("h:i:sa"))+($output3*60); 
$fertig=date("H:i:s",$date);

SetValueString(20388,$fertig);
SetValueInteger(52836, $date);

//var_dump($date);

Ja, das ist leider so.

Aus meiner Sicht sind die externen Befehle die einzige Möglichkeit, wo was hängen bleiben kann, weil das Skript auf deren Ausführung wartet, bevor es weiter macht.
Hast du mal IPS_Execute() mit Wartezeit versucht oder > /dev/null 2>/dev/null & ans Ende deines Befehls von exec() anzuhängen, damit die Ausführung von exec() asynchron läuft?

Aber dann kann es natürlich sein, dass dein Variablen-Status nicht mehr zu deinen Ausführungen passt.

Ich hatte letztens auch ein Script das exec() nutzte und hing. Als ich dann den Process auf der Konsole mit kill abgeschossen hatte - kam das Script wieder zurück :slight_smile:

Sonst gilt - wie hier schon geschrieben - geht nicht!

Gruß Heiko

Laufen die einzelnen PHP Prozesse separat sichtbar im Linux? Oder hast du das externe Programm abgeschossen?

Wenn es immer ein und das selbe externe Programm ist, kann man sich da schon was bauen, um es abzuschießen.

Ich hab das externe Programm abgeschossen!

Hallo zusammen,

ich habe ein klitzekleines Script, was mir Werte von der einen in eine andere Variable schreibt. Jetzt sprechen wir aber von KNX, wobei die gelesenen Werte zum Schreiben über eine WLAN Verbindung müssen. In 90% aller Fälle funktioniert das Perfekt, aber es kommt doch häufiger vor, das sich die Teilnehmer im Netz mal nicht finden, WLAN und UDP halt. Kommt aber keine Rückmeldung, wartet sich das Script zu Tode. Ich würde gerne dieses eine Script nach einer Zeit X beenden, in php gibt es ja da auch Möglichkeiten, die aber in Symcon nicht Funktionieren.

Ich habe auch schon eingehend Recherchiert, und bin nur auf Brechstangenmethoden und keine saubere Implementation gestoßen, wie das zu realsieren wäre. Auch sind die Forenbeiträge meiner Recherche im Minimum 3 Jahre alt. Das hier wäre der aktuellste, den ich finden konnte.

Da die Zeit ja nicht stillsteht, wollte ich mal Fragen, ob es mittlerweile eine Möglichkeit gibt, Scripte die zu lange laufen zu beenden, ohne gleich den ganzen Dienst abzuschiessen. Also analog zum set_time_limit, was ja nicht mehr geht. Dieses warten des Scripts dauert nämlich irgendwann so lange, das die maximale Scriptanzahl vollläuft, und Symcon einfach nicht mehr reagiert, was vorsichtig formuliert sehr ärgerlich ist.

Vielen Dank im voraus :slight_smile:

Welche Instanzen sind das wo du Werte schreiben willst? Die meisten Instanzen bzw Hardware Anbindungen in Symcon haben ein 5 Sekunden timeout und dann wird ein Skript mit Fehler beendet.
Michael

Hey, vielen Dank für die Antwort.
Das sind KNX Instanzen, bzw in Symcon UDP Socket genannt.
In den Einstellungen dieser Instanz kann ich keine Angabe für ein Timeout finden, sind die dann unveränderlich?

Hier mal das Script, von dem ich spreche, damit wird vll. mein Anliegen verdeutlicht :slight_smile:
Die ersten zwei habe ich jetzt einmal (seit 5 Minuten) ausgeklammert, um der Sache auf die Spur zu kommen.
Auch habe ich schon mit KNX_Write_DPTXX gearbeitet, was aber zum gleichen Ergebnis führte.
Es läuft durch dieses mini Script immer auf ein blockieren von Symcon hinaus, und ich komme, gerade weil nicht wirklich was drinn ist, nicht dahinter warum :frowning:
Das Script wird im Übrigen aufgerufen durch die Veränderung einer der drei gelesenen Variablen, was mich eben zum glauben führt, das es das schreiben sein muss, könnte eine Variable nicht gelesen werden, würde es ja theoretisch nicht zum Scriptaufruf kommen, richtig?

// Aktuelle Solarleistung
//$Calc_to_Positive = GetValueFloat(38213) * -1;
//RequestAction(16469, $Calc_to_Positive);

// Gesammte Solarleistung
//$Calc_to_Kw = GetValueInteger(56014) / 1000;
//RequestAction(45006, $Calc_to_Kw);

// Aussentemperatur
if(GetValueFloat(40427)){
    RequestAction(44013, GetValueFloat(40427));
}

Was soll die if-Abfrage deines Float 40427 bewirken?

Hey, Danke für deine Antwort,

ehrlich gesagt, das weiss ich nicht mehr, das Script ist so alt, ich hätte damals besser kommentieren sollen.

Ich nehme es mal raus, denn, spoiler, das Script bleibt immer noch hängen, auch mit nur diesen einen Sache darin.

Aber korrigiert mich, wenn ich hier flasch liege, es sollte doch eigentlich nichts ändern, ob die Abfrage da ist, oder nicht?

@Dreamdancer Naja, so eine if-Abfrage bekommt eigentlich einen Boolean um auf True/False zu prüfen. Hier gibtst du einen Float in diese Prüfung, ich habe keine Ahnung was PHP daraus macht. Einen Sinn erkenne ich in der if-Abfrage nicht, deshalb würde ich die rausnehmen.

Hey volkerm,
du magst recht haben, seit ich nach der letzten Antwort die Abfrage raus habe, bleibt das Script auch nicht mehr hängen.
Also erst einmal vielen Dank für die gelungene Hilfestellung :slight_smile:
Ich verstehe dein Argument mit Boolean und Float, ich frage mich bloss, warum es so lange mit dieser Abfrage kein Problem gab, und das dann jetzt auf einmal aufgetreten ist?
Da das Problem aber gelöst scheint, ist diese Antwort bloss für meine Neugier :smiley: