Verhalten list Befehl (Perl) in cmdalias einfache/doppelte Hochkomma

Begonnen von TomLee, 30 November 2022, 22:45:16

Vorheriges Thema - Nächstes Thema

TomLee

Das das Verhalten so ist das ein in Perl ausgeführtes list dann auch ins Log geschrieben wird hab ich heute gelernt.

Die Parameter von dem list werden mit ins Logfile geschrieben.

Was ich daran nicht verstehe:

Wenn ich in einem cmdalias den Übergabeparameter $EVTPART0 in einem list mit doppelten Hochkomma verwende:

defmod c_list2file cmdalias list2file .* AS {FileWrite("/opt/fhem/$EVTPART0.txt",fhem("list $EVTPART0"))}


Bekomm ich bei einem list2file d das zurück:
Zitat
2022.11.30 22:37:40 3: list d : Internals:
   CFGFN     
   FUUID      6387ca05-f33f-78f5-7089-358fa7b6cb982ada
   NAME       d
   NR         227739
   STATE      ???
   TYPE       dummy
Attributes:

$EVTPART0 wird evaluiert, das List ausgeführt.



Verwende ich einfache Hochkomma bei dem list Befehl:
defmod c_list2file cmdalias list2file .* AS {FileWrite("/opt/fhem/$EVTPART0.txt",fhem('list $EVTPART0'))}

Bekomm ich das zurück:

Zitat2022.11.30 22:41:20 3: list $EVTPART0 : Internals:
   CFGFN     
   FUUID      6387ca05-f33f-78f5-7089-358fa7b6cb982ada
   NAME       d
   NR         227739
   STATE      ???
   TYPE       dummy
Attributes:

Das List wird wieder ausgeführt, also $EVTPART0 wird schon evaluiert, aber nicht in der Zeile mit dem Zeitstempel.

Irgendwo passt da doch was nicht ?

OdfFhem

- Doppelte Anführungszeichen sorgen vor der Verwendung von Zeichenketten für das Ersetzen von Variablen.
- Einfache Anführungszeichen unterbinden eine solche Ersetzung.

TomLee

Mit dem Beispiel oben hab ich gezeigt das $EVTPART0, hier, in einfachen Klammern evaluiert wird, sonst gäbs den Logeintrag mit dem List nicht, die Frage ist und bleibt warum in der Zeile mit dem Timestamp nicht.

OdfFhem


{ my $test = "test";; Log 1, "$test" }
{ my $test = "test";; Log 1, '$test' }

sorgt für folgende Logeinträge

2022.11.30 23:39:44 1: test
2022.11.30 23:40:21 1: $test


Ohne ins Modul geschaut zu haben, wird bei fhem() vermutlich zunächst die Übergabe geloggt.
Anschließend wird dann die "evaluierte" Übergabe ausgeführt ...

TomLee

ZitatOhne ins Modul geschaut zu haben, wird bei fhem() vermutlich zunächst die Übergabe geloggt.
Anschließend wird dann die "evaluierte" Übergabe ausgeführt ...

Warum und wieso frag ich ja, warum ist das Verhalten so ?

Darauf gekommen bin ich ja nur wegen dem Beitrag (den ich zuerst gar nicht nachvollzogen hatte, bis mir das auffiel) und der offensichtlich auch vor dem teilen auf Funktion getestet war.

OdfFhem

Doch mal ins Modul geschaut ... fhem() sieht im relevanten Teil so aus:

  my ($param, $silent) = @_;
  my $ret = AnalyzeCommandChain(undef, $param);
  Log 3, "$param : $ret" if($ret && !$silent);


Bedeutet:
1) die übergebenen Parameter werden Variablen zugewiesen ... u.a. $param
... $param entspricht 1:1 der Parameterübergabe ... also list d oder list $EVTPART0
2) $param wird ausgewertet und das Ergebnis in $ret festgehalten
... das Auswerten findet quasi im selben Kontext statt wie der Aufruf
... daher wird im 2.Fall jetzt erst $EVTPART0 aufgelöst
3) falls möglich, wird $param und $ret ins Log geschrieben

OdfFhem

*** zur besseren Verdeutlichung mal ein Beispiel mit/ohne lokaler Variable

In der Kommandozeile führe ich immer list2file ftuitest aus.


Definition mit doppelten Anführungszeichen ... OHNE lokaler Variable:
* Raw definition ...
defmod c_list2file cmdalias list2file .* AS {FileWrite("/opt/fhem/backup/$EVTPART0.txt",fhem("list $EVTPART0"))}
* Logfile ...
2022.12.01 07:40:55.512 3: list ftuitest : ... list-Ergebnis von ftuitest ...


Definition mit doppelten Anführungszeichen ... MIT lokaler Variable:
* Raw definition ...
defmod c_list2file cmdalias list2file .* AS { my $evtpart0 = $EVTPART0;; FileWrite("/opt/fhem/backup/$EVTPART0.txt",fhem("list $evtpart0"))}
* Logfile ...
2022.12.01 07:42:20.920 3: list ftuitest : ...  list-Ergebnis von ftuitest ...



Definition mit einfachen Anführungszeichen ... OHNE lokaler Variable:
* Raw definition ...
defmod c_list2file cmdalias list2file .* AS {FileWrite("/opt/fhem/backup/$EVTPART0.txt",fhem('list $EVTPART0'))}
* Logfile ...
2022.12.01 07:44:44.600 3: list $EVTPART0 : ... list-Ergebnis von ftuitest ...


Definition mit einfachen Anführungszeichen ... MIT lokaler Variable:
* Raw definition ...
defmod c_list2file cmdalias list2file .* AS { my $evtpart0 = $EVTPART0;; FileWrite("/opt/fhem/backup/$EVTPART0.txt",fhem('list $evtpart0'))}
* Logfile ...
2022.12.01 07:46:22.794 3: list $evtpart0 : No device named $evtpart0 found



Hier wird deutlich, dass für fhem() bekannte (globale) Variablen wie $EVTPART0 auch noch später - beim "Evaluieren" - aufgelöst werden können.
Ein Versuch mit für fhem() unbekannten (lokalen) Variablen führt erwartungsgemäß zu einem Fehler.

TomLee

ZitatHier wird deutlich, dass für fhem() bekannte (globale) Variablen wie $EVTPART0 auch noch später - beim "Evaluieren" - aufgelöst werden können.
Ein Versuch mit für fhem() unbekannten (lokalen) Variablen führt erwartungsgemäß zu einem Fehler.

Danke für die Mühe, mit der Erklärung ist das Verhalten für mich nachvollziehbar.

TomLee

Was mich weiterhin irritiert bei der "Anzeige" im Log, ist, das das List nach dem Doppelpunkt beginnt, spricht was dagegen wenn man nach dem Doppelpunkt einen Zeilenumbruch ergänzt ?

OdfFhem

Zitat von: TomLee am 01 Dezember 2022, 08:45:25
Was mich weiterhin irritiert bei der "Anzeige" im Log, ist, das das List nach dem Doppelpunkt beginnt, spricht was dagegen wenn man nach dem Doppelpunkt einen Zeilenumbruch ergänzt ?
Den Zeilenumbruch fände ich auch besser ...

Aus

  Log 3, "$param : $ret" if($ret && !$silent);

würde / könnte werden

  Log 3, "$param\n$ret" if($ret && !$silent);

So sparen wir sogar ein Zeichen ;)

Vielleicht wird @rudolfkoenig auf den "Änderungswunsch" aufmerksam ...

Beta-User

Zitat von: TomLee am 01 Dezember 2022, 00:00:33
Warum und wieso frag ich ja, warum ist das Verhalten so ?
Des Rätsels Lösung dürfte in "EvalSpecials" liegen. Damit werden in "fhem-eval" (indirekt via AnalyzeCommandChain()) bestimmte Parameter (für eine gewisse Zeit persistent) übergeben...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files