myUtils: Zeitpunkt der letzten Änderung von Datei ermitteln

Begonnen von yersinia, 02 Februar 2024, 08:33:51

Vorheriges Thema - Nächstes Thema

yersinia

Hallo zusammen,

ich benötige den letzten Änderungszeitpunkt einer Datei für die weitere Verarbeitung in der myUtils. Dafür scheint mir File::stat mit
Zitat9 mtime    last modify time in seconds since the epoch
ganz gut geeignet.

Um den Fehler besser eingrenzen zu können, nutze ich diese Testfunktion:
##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;

use strict;
use warnings;
use POSIX;

sub
myUtils_Initialize($$)
{
  my ($hash) = @_;
}

# Enter your functions below _this_ line.

sub myTest {
#call: {main::myTest()}
my @missingmodules = ();
  eval "use File::stat qw( );1;" or push (@missingmodules, "File::stat");
eval "use Time::Piece qw( );1;" or push (@missingmodules, "Time::Piece");
eval "use DateTime                  qw( );1;" or push (@missingmodules, "DateTime");

if(scalar @missingmodules > 0) {
    my $retmsg = "collected missing module";
$retmsg .= scalar @missingmodules > 1 ? "s: " : ": ";
$retmsg .= join('\n',@missingmodules);
return $retmsg;
}

my $filename = "www/test.txt";
my $filemtime = DateTime->from_epoch( epoch => ((stat($filename))->mtime), time_zone => 'local', );

return $filemtime->strftime('%Y-%m-%d_%H-%M-%S');
}

1;
wobei die Datei für FHEM erreichbar und lesbar ist:
ls -lah /opt/fhem/www
drwxr-xr-x 12 fhem dialout 4,0K 14. Jan 21:21 .
drwxr-xr-x 14 fhem dialout 4,0K  2. Feb 07:57 ..
-rw-r--r--  1 fhem dialout 1,3K 14. Jan 21:21 test.txt

Rufe ich die sub nach einem Edit in myUtils auf, bekomme ich ein valides Ergebnis.
2024-01-14_21-21-10
Nach einem FHEM-Restart erhalte ich allerdings eine Fehlermeldung:
Can't locate object method "mtime" via package "1" (perhaps you forgot to load "1"?) at ./FHEM/99_myUtils.pm line 36.Führe ich eine Änderung in der myUtils durch und speichere, funktioniert das Auslesen des letzten Änderungszeitpunkts wieder wie gewohnt (wahrscheinlich wird die myUtils dann auch neu geladen).

Der Zugriff über
(stat($filename))[9]führt leider nicht zu dem gewünschten Ergebnis.

Aus dem FHEM Wiki ist mir nicht ersichtlich, ob FHEM über FileRead (o.ä.) derartige Metainformationen zur Verfügung stellt.

Als perl-noob ist mir nicht ganz klar, was hier fehlt - wohlmöglich verwende ich gewissen Code einfach falsch  ::)  - und hab aber irgendwie auch keine Idee, wie ich gezielt nach der Behebung des Fehlers suchen kann. Vlt gibt es hier jmd, welcher mich in die richtige Richtung schubsen kann. :)

FHEM Version ist 28462, perl v5.32.1.

Danke vorab.
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

JoWiemann

#1
Hallo,

hast Du den Hinweis berücksichtig:

# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

Unter welchem Namen hast Du gespeichert? Nur Module mit 99_ werden beim Start von Fhem immer geladen. Alle anderen nur, wenn ein Device für das Modul definiert worden ist.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

yersinia

#2
Ja, hab ich. Die Datei ist als 99_myUtils.pm gespeichert - über FHEMWEB Interface Edit files > Save 99_myUtils.pm. Ich habe aber auch gelesen:
# Enter your functions below _this_ line.
Wenn die 99_myUtils.pm beim Start nicht geladen wird, müsste ich dann nicht auch mit anderen Funktionen initial Probleme haben? Oder ich verstehe noch nicht, wie FHEM die Module lädt.

EDIT: laut Wiki-Eintrag werden alle 99_er pms beim Start geladen:
ZitatDer Dateiname muss mit 99_ beginnen. FHEM lädt beim Start alle Programmdateien mit dem prefix 99_.
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

JoWiemann

Hm,

ich würde erst einmal alle externen Module ohne eval laden. Nur so bekommst Du aussagefähige Fehlermeldungen. eval ist da ziemlich stumpf.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

betateilchen

Die ganze Funktion in Deiner myUtils.pm sieht extrem komisch aus.
Wie kommst Du denn auf den Inhalt?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Dein Problem liegt hier:

((stat($filename))->mtime)
Es gibt kein gültiges Objekt, für das du die Methode mtime aufrufen könntest. Da ist ein Klammernpaar zuviel.

Die von Dir extra eingebundenen Module sind ohnehin in perl enthalten und müssen nicht separat geladen werden. Deshalb funktioniert bei mir folgende Funktion, ohne dass ich irgendwelche perl Module in meiner 99_myUtils.pm zusätzlich angeben muss.

sub test {
  my $filename = "./fhem.pl";
  my $filemtime = DateTime->from_epoch( epoch => (stat($filename))[9], time_zone => 'local', );
  return $filemtime->strftime('%Y-%m-%d_%H-%M-%S');
}
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

yersinia

#6
Definiere extrem komisch. Den Code muss ich dir wahrscheinlich nicht erklären, die erste Hälfte ist sowieso nur nice2have.

Um den letzten Änderungszeitpunkt zu erhalten fand ich File::stat und stat passend. Da mtime aber Sekunden seit epoch darstellt hätte ich dies gern in ein "einfacheres" Zeitobjekt umgewandelt. Dafür schien mir DateTime passend. Also: Änderungszeitpunkt von File auslesen und in DateTime Objekt konvertieren, mehr sollte diese Zeile nicht tun:
    my $filename = "www/test.txt";
    my $filemtime = DateTime->from_epoch( epoch => ((stat($filename))->mtime), time_zone => 'local', );
Mich wundert, dass es initial funktioniert und nach einem Neustart von FHEM es zu einer Fehlermeldung kommt. Meine Vermutung war, dass packages (zB für File::stat) fehlen - und hatte gehofft, diese über eval-Prüfung abgefangen zu bekommen.

Das fehlende gültige Objekt habe ich auch heraus gelesen - aber warum ist das Objekt nur nach FHEM-Restart ungültig? Nach einer Änderung zu FHEM-Laufzeit und reload der myUtils funktioniert der Code ja.

Wenn ich
  my $filemtime = DateTime->from_epoch( epoch => (stat($filename))[9], time_zone => 'local', );nutze, dann erhalte ich folgende Fehlermeldung:
Validation failed for type named Num declared in package Specio::Library::Builtins (/usr/share/perl5/Specio/Library/Builtins.pm) at line 138 in sub named (eval) with value undef

Trace begun at Specio::Exception->new line 57
Specio::Exception::throw('Specio::Exception', 'message', 'Validation failed for type named Num declared in package Specio::Library::Builtins (/usr/share/perl5/Specio/Library/Builtins.pm) at line 138 in sub named (eval) with value undef', 'type', 'Specio::Constraint::Simple=HASH(0x55984e2ea8)', 'value', undef) called at (eval 208) line 88
DateTime::_check_from_epoch_params('epoch', undef, 'time_zone', 'local') called at /usr/lib/aarch64-linux-gnu/perl5/5.32/DateTime.pm line 481
DateTime::from_epoch('DateTime', 'epoch', undef, 'time_zone', 'local') called at FHEM/99_myUtils.pm line 41
main::myTest at (eval 38724) line 1
eval '{main::myTest()}' at fhem.pl line 1177
main::AnalyzePerlCommand('HASH(0x55a2f055e8)', '{main::myTest()}', 1) called at fhem.pl line 1206
main::AnalyzeCommand('HASH(0x55a2f055e8)', '{main::myTest()}', 'ACC') called at fhem.pl line 1133
main::AnalyzeCommandChain('HASH(0x55a2f055e8)', '{main::myTest()}') called at FHEM/01_FHEMWEB.pm line 2863
main::FW_fC('{main::myTest()}', '') called at FHEM/01_FHEMWEB.pm line 1025
main::FW_answerCall('/fhem&fw_id=1706873122.72457&fwcsrf=csrf_458894268802172&cmd=%7Bmain%3A%3AmyTest%28%29%7D') called at FHEM/01_FHEMWEB.pm line 609
main::FW_Read('HASH(0x55a2f055e8)') called at fhem.pl line 3985
main::CallFn('WEB_192.168.0.233_54996', 'ReadFn', 'HASH(0x55a2f055e8)') called at fhem.pl line 786

stat($filename))[9]scheint undef zurückzugeben:
DateTime::_check_from_epoch_params('epoch', undef, 'time_zone', 'local') called at /usr/lib/aarch64-linux-gnu/perl5/5.32/DateTime.pm line 481
DateTime::from_epoch('DateTime', 'epoch', undef, 'time_zone', 'local') called at FHEM/99_myUtils.pm line 41

return stat($filename)->mtimeergibt immerhin 1705263670.

EDIT: vlt war auch nur die Klammerung zuviel, ich werds testen
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

betateilchen

Zitat von: yersinia am 02 Februar 2024, 12:37:18Definiere extrem komisch.

kann es sein, dass Du in einer völlig ungewöhnlichen perl-Umgebung unterwegs bist?

Was ist das?

package Specio::Library::Builtins
Wie gesagt - mein Codebeispiel aus dem vorigen Beitrag funktioniert problemlos und liefert 2024-01-29_19:50:15

(This is perl 5, version 32, subversion 1 (v5.32.1))
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

yersinia

#8
Zitat von: betateilchen am 02 Februar 2024, 12:44:23kann es sein, dass Du in einer völlig ungewöhnlichen perl-Umgebung unterwegs bist?
Ich nutze die perl-Umgebung welche mit RaspiOs Bullseye (derzeit 11.8 ) mitkommt: This is perl 5, version 32, subversion 1 (v5.32.1) built for aarch64-linux-gnu-thread-multi

Zitat von: betateilchen am 02 Februar 2024, 12:44:23Was ist das?
package Specio::Library::Builtins
libspecio-perl wird benötigt von libdatetime-perl, welches wiederum von libdatetime-format-ical-perl benötigt wird. libdatetime-format-ical-perl benötige ich für Erstellung von ical-Kalendern.
apt-cache rdepends libspecio-perl
libspecio-perl
Reverse Depends:
  libcode-tidyall-perl
  libdatetime-timezone-perl
  libtype-tie-perl
  libspecio-library-path-tiny-perl
  libspecio-library-path-tiny-perl
  libmarkdent-perl
  liblog-dispatch-perl
  libdatetime-timezone-perl
  libdatetime-perl
  libdatetime-locale-perl
  libdatetime-format-strptime-perl
  libdatetime-format-iso8601-perl
Dennoch interessant, dass Specio::Library::Builtins hier Problemverursacher zu sein scheint.
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

TomLee

Hallo,

mag nicht verwirren, nur aufzeigen das ich die gleichen Meldungen zurückbekomme mit:

This is perl 5, version 36, subversion 0 (v5.36.0) built for aarch64-linux-gnu-thread-multi

sub fupy {
  my $filename = "./fhem.pl";
  my $filemtime = DateTime->from_epoch( epoch => (stat($filename))[9], time_zone => 'local', );
  return $filemtime->strftime('%Y-%m-%d_%H-%M-%S');
}

Validation failed for type named Num declared in package Specio::Library::Builtins (/usr/share/perl5/Specio/Library/Builtins.pm) at line 138 in sub named (eval) with value undef

Trace begun at Specio::Exception->new line 57
Specio::Exception::throw('Specio::Exception', 'message', 'Validation failed for type named Num declared in package Specio::Library::Builtins (/usr/share/perl5/Specio/Library/Builtins.pm) at line 138 in sub named (eval) with value undef', 'type', 'Specio::Constraint::Simple=HASH(0x5573acd970)', 'value', undef) called at (eval 250) line 88
DateTime::_check_named_from_epoch_params('epoch', undef, 'time_zone', 'local') called at /usr/lib/aarch64-linux-gnu/perl5/5.36/DateTime.pm line 493
DateTime::from_epoch('DateTime', 'epoch', undef, 'time_zone', 'local') called at FHEM/99_myUtils.pm line 90
main::fupy at (eval 12092) line 1
eval '{fupy}' at fhem.pl line 1177
main::AnalyzePerlCommand('HASH(0x557e8123c0)', '{fupy}', 1) called at fhem.pl line 1206
main::AnalyzeCommand('HASH(0x557e8123c0)', '{fupy}', 'ACC') called at fhem.pl line 1133
main::AnalyzeCommandChain('HASH(0x557e8123c0)', '{fupy}') called at FHEM/01_FHEMWEB.pm line 2863
main::FW_fC('{fupy}', '') called at FHEM/01_FHEMWEB.pm line 1025
main::FW_answerCall('/fhem&fw_id=1706877516.30063&fwcsrf=xxx&cmd=%7Bfupy%7D') called at FHEM/01_FHEMWEB.pm line 609
main::FW_Read('HASH(0x557e8123c0)') called at fhem.pl line 3985
main::CallFn('WEB_192.168.188.21_57782', 'ReadFn', 'HASH(0x557e8123c0)') called at fhem.pl line 786

yersinia

@TomLee: hast du auch libspecio-perl als Abhängigkeit anderer Pakete installiert?
libspecio-perl
Reverse Depends:
  libcode-tidyall-perl
  libdatetime-timezone-perl
  libtype-tie-perl
  libspecio-library-path-tiny-perl
  libspecio-library-path-tiny-perl
  libmarkdent-perl
  liblog-dispatch-perl
  libdatetime-timezone-perl
  libdatetime-perl
  libdatetime-locale-perl
  libdatetime-format-strptime-perl
  libdatetime-format-iso8601-perl
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

TomLee

Nicht das ich wüsste, wie prüfe ich das genau?
So ?
pi@fhempi:~ $ perl -Mlibspecio-perl
Can't locate libspecio.pm in @INC (you may need to install the libspecio module) (@INC contains: /etc/perl /usr/local/lib/aarch64-linux-gnu/perl/5.36.0 /usr/local/share/perl/5.36.0 /usr/lib/aarch64-linux-gnu/perl5/5.36 /usr/share/perl5 /usr/lib/aarch64-linux-gnu/perl-base /usr/lib/aarch64-linux-gnu/perl/5.36 /usr/share/perl/5.36 /usr/local/lib/site_perl).
BEGIN failed--compilation aborted.
Dann nicht .

Per cpan hab ich sicher nix installiert.

yersinia

viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

TomLee

Ok, es ist installiert.
pi@fhempi:~ $ dpkg -l libspecio-perl
Gewünscht=Unbekannt/Installieren/R=Entfernen/P=Vollständig Löschen/Halten
| Status=Nicht/Installiert/Config/U=Entpackt/halb konFiguriert/
         Halb installiert/Trigger erWartet/Trigger anhängig
|/ Fehler?=(kein)/R=Neuinstallation notwendig (Status, Fehler: GROSS=schlecht)
||/ Name           Version      Architektur  Beschreibung
+++-==============-============-============-====================================================
ii  libspecio-perl 0.48-1       all          Perl module providing type constraints and coercions
pi@fhempi:~ $ apt policy libspecio-perl
libspecio-perl:
  Installiert:           0.48-1
  Installationskandidat: 0.48-1
  Versionstabelle:
 *** 0.48-1 500
        500 http://deb.debian.org/debian bookworm/main arm64 Packages
        500 http://deb.debian.org/debian bookworm/main armhf Packages
        100 /var/lib/dpkg/status

Aber das ich es selbst im nachhinein installiert habe schliesse ich eigentlich aus, ich bin der Meinung das ich alles dokumentiert hab was ich nachträglich installiert habe und da steht nix von libspecio-perl dabei.

betateilchen

Interessant...

ii  libspecio-perl 0.47-1       all          Perl module providing type constraints and coercions

Bewusst nachinstalliert habe ich das nicht.

Wenn ich mir die Verzeichnisstruktur von perl auf meinem Rechner anschaue, dann gehört das offenbar zur Standardinstallation von perl, es wurde auch am Tag der Inbetriebnahme des Rechners zusammen mit dem kompletten perl installiert.

Das zugrundeliegende Debian hier ist noch ein 11.8.
Für Bookworm kommt die libspecio wohl in der Version 0.48
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

#15
@yersinia

Auf die Gefahr hin das ich nicht alles richtig verstanden habe was genau gewünscht ist:
Wäre es nicht auch einfach OK stat mit der Option %Z zu verwenden, welche die Epoch-Sekunden zurückgibt ?
Nur die benötigt man doch zur weiteren Verwendung in einer myUtils ? Oder geht es darum, auf möglichst kürzestem Weg, genau das Zeitformat %Y-%m-%d_%H-%M-%S zu erhalten um das irgendwo auszugeben ?
sub fupy {
my $t = system("stat -c '%Z' testjson.json");
return $t;
}



betateilchen

#16
warum sollte man das auf Betriebssystemebene machen, wo doch stat() eine perl Standardfunktion ist?

(stat("fileName"))[9]
liefert auch die Sekunden zurück, die man dann beliebig formatieren kann.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

yersinia

Ich benötige den Zeitpunkt der letzten Änderung um diesen dann weiter verarbeiten zu können; am liebsten als DateTime-Objekt - das Zielformat ist
%Y%m%dT%H%M%S
Allerdings bekomme ich mit
my $t = system("stat -c '%Z' www/test.txt");nur den Rückgabewert -1.

Zitat von: betateilchen am 02 Februar 2024, 16:41:03warum sollte man das auf Betriebssystemebene machen, wo doch stat() eine perl Standardfunktion ist?
Davon abgesehen. Ich gehe davon aus, dass perl auch im FHEM-Kontext fähig ist, Metainformationen einer Datei abzufragen.
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

betateilchen

Zitat von: yersinia am 02 Februar 2024, 16:43:11Davon abgesehen. Ich gehe davon aus, dass perl auch im FHEM-Kontext fähig ist, Metainformationen einer Datei abzufragen.

Natürlich - siehe die Ergänzung in meinem letzten Beitrag.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

yersinia

Wo wir wieder hier wären:
Zitat von: yersinia am 02 Februar 2024, 12:37:18stat($filename)[9]scheint undef zurückzugeben:
DateTime::_check_from_epoch_params('epoch', undef, 'time_zone', 'local') called at /usr/lib/aarch64-linux-gnu/perl5/5.32/DateTime.pm line 481
DateTime::from_epoch('DateTime', 'epoch', undef, 'time_zone', 'local') called at FHEM/99_myUtils.pm line 41
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

betateilchen

#20
Logisch, das ist ja auch falsch. Es muss

(stat($filename))[9]
heißen. stat() liefert ein array, Du willst aus dem array das Element 9 haben. Also musst Du auch das array korrekt übergeben, wenn Du es nicht einer Variablen zuweisen möchtest. Deshalb die zusätzlichen Klammern (die übrigens auch in meinem Codebeispiel stehen !)



Aber...

Zitat von: yersinia am 02 Februar 2024, 16:43:11Ich benötige den Zeitpunkt der letzten Änderung um diesen dann weiter verarbeiten zu können; am liebsten als DateTime-Objekt - das Zielformat ist
%Y%m%dT%H%M%S

Das ist doch noch einfacher zu lösen:

sub test {
  my $filename = "./fhem.pl";
  return POSIX::strftime("%Y%m%dT%H%M%S",localtime((stat($filename))[9]));
}

liefert

20240129T195015
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

#21
Zitat von: yersinia am 02 Februar 2024, 16:43:11Allerdings bekomme ich mit
Code Auswählen Erweitern

my $t = system("stat -c '%Z' www/test.txt");nur den Rückgabewert -1.

Du musst im Log schauen.



sub test {
  my $filename = "./fhem.pl";
  return POSIX::strftime("%Y%m%dT%H%M%S",localtime((stat($filename))[9]));
}

Und was ist hier jetzt der Grund dafür das man das POSIX:: vor strftime weglassen kann ?

betateilchen

Zitat von: TomLee am 02 Februar 2024, 17:27:53Und was ist hier jetzt der Grund dafür das man das POSIX:: vor strftime weglassen kann ?

Das ist nicht ganz die passende Frage.

Die richtige Frage wäre, warum ich das POSIX:: hier explizit angegeben habe.
Antwort: ich bin für klare Verhältnisse, deshalb gebe ich an, aus welchem Modul ich die Funktion strftime() haben möchte, für den Fall, dass es die Funktion in mehreren Modulen oder z.B. in der 99_myUtils.pm geben könnte.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

OK, vielen Dank.


Zitatstat() liefert ein array, Du willst aus dem array das Element 9 haben. Also musst Du auch das array korrekt übergeben, wenn Du es nicht einer Variablen zuweisen möchtest. Deshalb die zusätzlichen Klammern

Und ich verstehe aber immer noch nicht warum man sich die Sekunden nicht ausgeben lassen kann (einfach nur zum nachvollziehen), es klappt nicht mit Debug, und auch nicht wenn ich es in einer Variablen festhalten möchte, nur als Parameterübergabe in dem strftime.
Bspw. beim schnell ausprobieren in der Befehlszeile, das gleiche gilt aber auch in der myUtils:
{my $t=(stat('./fhem.pl'))[9];;return $t;;}
{my $t=(stat('./fhem.pl'))[9];;Debug $t;;}

betateilchen

Zitat von: TomLee am 02 Februar 2024, 17:58:06Und ich verstehe aber immer noch nicht warum man sich die Sekunden nicht ausgeben lassen kann

Bei mir funktioniert das einwandfrei.

In die Befehlszeile eingegeben

{my $t=(stat('./fhem.pl'))[9];;return $t;;}
erhalte ich als Antwort im Frontend

1706554215
Deine Zeile mit Debug funktioniert bei mir genauso fehlerfrei:

2024.02.02 18:03:49 1: DEBUG>1706554215
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

Bei mir funzt das nicht, weder am Laptop, noch jetzt wo ich es nochmal am Tablet ausprobiert habe, nachdem du geschrieben hast.

Am allgemeinen Zustand kanns auch nicht liegen, das Fläschchen Bier hab ich eben erst aufgemacht.

TomLee

#26
Anbei der Nachweis...

sub fupy {
  #my $filename = "./fhem.pl";
  #return strftime("%Y%m%dT%H%M%S",localtime((stat($filename))[9]));
  my $t=(stat('./fhem.pl'))[9];
  Debug $t;
  return $t;
}



Ja ich weiß das es jetzt was von OT hat, evtl. aber auch nicht.

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

Ich sag mal so, sicher kannst auch du es bei Dir genauso nachvollziehen:

Wenn man "oben" in der myUtils:
use File::stat;
use Time::Piece;
use DateTime;
zusätzlich angegeben hat  ::) , dann kommt es genau zu meinem geschilderten Verhalten.
Nimmt man das wieder raus und macht einen restart, dann ist das Elend vorbei  ;)

betateilchen

Zitat von: TomLee am 02 Februar 2024, 20:30:04Wenn man "oben" in der myUtils:
use File::stat;

Natürlich funktioniert es dann NICHT.
Das brauche ich gar nicht nachvollziehen, das steht sogar ausdrücklich in der Beschreibung zu File::stat.

ZitatThis module's default exports override the core stat() and lstat() functions, replacing them with versions that return "File::stat" objects.

Das heißt doch eindeutig: die Sache mit dem array funktioniert dann nicht mehr, weil es gar kein array mehr als Rückgabewert gibt.

Aber davon, dass diese Dinge bei Dir explizit angegeben sind, war bisher nirgends die Rede.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TomLee

#30
OK, und jetzt ? Ich hab keine Doku zwischenzeitlich gewälzt, zum eigentlichen Problem zeigt das jetzt doch, das es nur wie von Jowiemann anfangs schon angedeutet an diesen eval-Deklarationen in der Sub myTest von yersinia liegt :

eval "use File::stat qw( );1;" or push (@missingmodules, "File::stat");
eval "use Time::Piece qw( );1;" or push (@missingmodules, "Time::Piece");
eval "use DateTime                  qw( );1;" or push (@missingmodules, "DateTime");

yersinia

Zitat von: betateilchen am 02 Februar 2024, 17:01:40Logisch, das ist ja auch falsch. Es muss
(stat($filename))[9]heißen. stat() liefert ein array, Du willst aus dem array das Element 9 haben. Also musst Du auch das array korrekt übergeben, wenn Du es nicht einer Variablen zuweisen möchtest. Deshalb die zusätzlichen Klammern (die übrigens auch in meinem Codebeispiel stehen !)
Aber auch nur dann, wenn File::stat nicht doch noch einmal in der Instanz geladen worden ist. Und dies ist auch, so vermute ich, der Grund, warum bei mir
(stat($filename))[9]nicht mehr funktioniert ohne die Instanz neuzustarten. Starte ich FHEM neu, funktioniert der Code direkt ohne Probleme. Lade ich eine myUtils neu, die zufällig noch use File::stat lädt, liefert stat undef zurück.

Zitat von: betateilchen am 02 Februar 2024, 17:01:40Aber...
Zitat von: yersinia am 02 Februar 2024, 16:43:11Ich benötige den Zeitpunkt der letzten Änderung um diesen dann weiter verarbeiten zu können; am liebsten als DateTime-Objekt - das Zielformat ist
%Y%m%dT%H%M%S
Das ist doch noch einfacher zu lösen:
sub test {
  my $filename = "./fhem.pl";
  return POSIX::strftime("%Y%m%dT%H%M%S",localtime((stat($filename))[9]));
}
liefert
20240129T195015
Ich hab mir meinen Code (für die Weiterverarbeitung des Änerungszeitpunkts) nochmal angesehen, das DateTime Objekt ist hier wirklich unnötig, da reicht dein Lösungsvorschlag vollkommen aus. Manchmal denkt man zu kompliziert, danke für den Vorschlag.

Zitat von: betateilchen am 02 Februar 2024, 20:58:25Natürlich funktioniert es dann NICHT.
Das brauche ich gar nicht nachvollziehen, das steht sogar ausdrücklich in der Beschreibung zu File::stat.
ZitatThis module's default exports override the core stat() and lstat() functions, replacing them with versions that return "File::stat" objects.
Das heißt doch eindeutig: die Sache mit dem array funktioniert dann nicht mehr, weil es gar kein array mehr als Rückgabewert gibt.
Das hab ich echt überlesen und kann ich bestätigen; eigtl ist dies eine logische Konsequenz - entweder stat liefert ein array zurück (perl Standard (?)) oder es wird zu einem File::stat Objekt wenn man das Modul einmalig in die Instanz lädt.
Wenn dem aber so wäre,
ZitatThis module's default exports override the core stat() and lstat() functions, replacing them with versions that return "File::stat" objects. This object has methods that return the similarly named structure field name from the stat(2) function; namely, dev, ino, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, blksize, and blocks.
dann dürfte dieser Fehler
ZitatCan't locate object method "mtime" via package "1" (perhaps you forgot to load "1"?) at ./FHEM/99_myUtils.pm line 36.
gar nicht auftreten, da durch das Laden via use File::stat die Objektmethode auf jedenfall vorhanden sein müsste. (Und ich glaube nicht, dass FHEM hier in irgendeiner Weise der Verursacher wäre)
Oder ich nutze stat($filename)->mtime falsch - oder man gibt für stat das pseudo CORE package an:
return POSIX::strftime("%Y%m%dT%H%M%S",localtime((CORE::stat($filename))[9]));
Danke jdfs für den Input, damit hoffe ich die Fehlermeldung bei initialer Ausführung zu umgehen.  :)
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

betateilchen

#32
Zitat von: yersinia am 03 Februar 2024, 16:11:42Oder ich nutze stat($filename)->mtime falsch

Jepp. Richtig wäre:

(stat($filename))->mtime;
Vereinfacht gesagt die Begründung:
Ein Funktionsaufruf alleine ist noch kein Objekt mit Methoden, das Ergebnis des Funktionsaufrufs sehr wohl.
Deshalb die zusätzlichen Klammern.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Zitat von: yersinia am 03 Februar 2024, 16:11:42Starte ich FHEM neu, funktioniert der Code direkt ohne Probleme. Lade ich eine myUtils neu, die zufällig noch use File::stat lädt,

Hast Du denn überhaupt einen triftigen Grund, die ohnehin im Standard vorhandene Funktion stat() durch die Funktion aus File::stat zu ersetzen?

Anders gefragt: warum benutzt Du überhaupt irgendwo File::stat?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

yersinia

Zitat von: betateilchen am 03 Februar 2024, 18:10:07Jepp. Richtig wäre:

(stat($filename))->mtime;
Vereinfacht gesagt die Begründung:
Ein Funktionsaufruf alleine ist noch kein Objekt mit Methoden, das Ergebnis des Funktionsaufrufs sehr wohl.
Deshalb die zusätzlichen Klammern.
Ja, stimmt, so nutze ich es auch - hab es hier falsch zitiert. ::)

Zitat von: betateilchen am 03 Februar 2024, 18:44:35Hast Du denn überhaupt einen triftigen Grund, die ohnehin im Standard vorhandene Funktion stat() durch die Funktion aus File::stat zu ersetzen?

Anders gefragt: warum benutzt Du überhaupt irgendwo File::stat?
File::stat hab ich genutzt, weil stat nicht zum laufen bekommen habe - zumindest schien mir File::stat auch als die "bessere" Option. Allerdings habe ich nun keinen Grund mehr File::stat zu nutzen und kann das Laden des Moduls weglassen.
Für die Zukunft sollte ich allerdings die Testfunktionen sauberer kapseln - und nicht, wie in diesem Szenario, in der gleichen myUtils mit anderen Funktionen welche noch File::stat laden.

Danke jdfs fürs Analyzieren und die investierte Zeit - mit dem einfacheren Lösungsvorschlag und core-stat sollte ich besser, robuster fahren. Ich werds' beobachten. Merci.
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl