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!