PDF an Hand des hinterlegten barcodes umbenennen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 14.04.2022 22:19:39

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
(geht davon aus, dass ich sämtliche Feinheiten finde :oops: :mrgreen: :oops: 8O )
Soo, etwas verspätet dann noch ein paar Erklärungen. Ich hoffe, ich sorge nicht für noch mehr Verwirrung ;)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

#!/bin/bash
legt die zu verwendende shell fest
Hmm, in gewisser Weise, ja. Man kann ein Shellskript auch immer ohne diese erste Zeile als

Code: Alles auswählen

~$ sh mein_skript
~$ bash mein_skript
ausführen. Dann muss man aber wissen, welche Shell (häufige Frage: Bash oder nicht Bash) das Skript braucht. Macht man ein Skript ausführbar (z.B. mit chmod +x) und zusammen mit dieser ersten Shebang-Zeile übernimmt dann das Betriebssystem das Aufrufen der angegebenen Shell. Und übergibt dieser den Namen des abzuarbeitenden Skripts. Das Skript wird dann äquivalent zu den beiden obigen Zeilen aufgerufen, man kann es wie ein „richtiges“ Programm verwenden:

Code: Alles auswählen

~$ ./mein_skript
Die Shebang-Zeile ist nicht nur für Shellskripte relevant, sondern auch Python, Perl, awk, manchmal Makefiles etc. etc. Prinzipiell kann man in der Shebang-Zeile ein beliebiges Programm – einen Interpreter für diese (Skript-) Datei – angeben, das aufgerufen wird und den Namen der (Skript-)Datei übergeben bekommt.


letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

set -eu -o pipefail
beenden wenn Nicht-Null-Status oder nicht gesetzte Variablen für die Variable pipefail
Verstehe ich nicht. pipefail wird doch nicht definiert?
pipefail ist eine Option, die keine Kurzform wie das -e und -u hat. Was sie bewirkt, verrät dir

Code: Alles auswählen

~$ help set
Ich hatte sie hier gesetzt, damit (in Kombination mit -e) das ganze Skript fehlschlägt, wenn in den beiden Funktionen zum Umwandeln von PDF zu Text etwas scheitert. (Die beide eine Pipeline … | … benutzen.)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destname_pdftotext()
Hmmm. destname-Erklärung im eigentlichen Sinne nicht gefunden.
Das ist einfach eine Funktionsdefinition, „destname_pdftotext“ ist der volle Funktionsname. Man kann es auch als

Code: Alles auswählen

function destname_pdftotext()
schreiben, aber das ist Bash-spezifisch und m.M.n. unnötig viel zu tippen. Die Funktion würde in anderen Sprachen ganz grob so aussehen, vielleicht hilfts mit Signatur:

Code: Alles auswählen

# C++
std::string destname_pdftotext(const std::string& pdf_path);

# C
int destname_pdftotext(const char *pdf_path, char *str, size_t len);

# Python
def destname_pdftotext(pdf_path: str) -> str

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

{
	pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}
Wende pdftotext auf das Dokument (welches?) an. Greppe dann bis die Zahl 1 mal gefunden wurde (-m1).
Ratemodus für "^\ -> alles innerhalb der *
Sammle nur Ziffern 0-9, für YYYY-MM-DD
Setze _
Das ist nun der Inhalt der Funktion und mehr oder weniger die einzelnen Schritte zusammengeschrieben, die ihr vorher schon ausprobiert hattet. Beide Funktionen hier werden (weiter unten) mit dem Pfad einer PDF-Datei als Argument aufgerufen:

Code: Alles auswählen

destname_pdftotext "/somewhere/over/the/rainbow.pdf"
In anderen Sprachen wäre das Argument oft in Klammern, hier nicht. Das Argument wird dann über $1 verwendet, da es das 1. Funktionsargument ist. Die Funktionsargumente werden in Skripten nicht per Namen (wie das pdf_path in den drei Beispielen oben), sondern nur über ihre Position beim Funktionsaufruf angesprochen.

Code: Alles auswählen

pdftotext "$1" -
In der Funktion wird also als erstes pdftotext mit der PDF-Datei aufgerufen. Das Minus als zweites Argument ist eine oft benutzte Konvention, die dem Programm sagt, dass es sein Ergebnis nicht in eine Datei schreiben soll, sondern direkt auf die Standardausgabe. pdftotext kann das praktischerweise auch. Damit spart man sich hier eine temporäre Datei, die man anschließend wieder löschen müsste.

Code: Alles auswählen

… | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$"
Die Ausgabe von pdftotext – der Text des PDFs – wird über eine Pipe | direkt an grep weitergegeben. Deshalb sieht man die Ausgabe von pdftotext auch nicht tatsächlich auf dem Bildschirm. Den Suchausdruck hatte ich, meine ich, von euren vorherigen Schritten kopiert. Genau, das -m1 sorgt dafür, dass höchstens ein grep-Ergebnis weitergegeben wird. Ähnlich wie ein head -1, was im Thread auch auftauchte. Ist ein Baustein, um fehlerhafte Umbenennungen auszuschließen.

Code: Alles auswählen

… | tr -d '*'
Das tr entfernt abschließend noch die Sternchen vorne und hinten, die Zeile im PDF sah ja so aus: *2022-03-24_20123988*. Und ohne die Sternchen ist es ja praktischerweise direkt der Zieldateiname. (Oder hab ich dabei was übersehen?)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
es verlässt mich :cry:
Dran bleiben! ;)

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Frage: kann anstelle von [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] auch [:digit:]-[:digit:]-[:digit:] verwendet werden?
Fast. [:digit:] ersetzt ein 0-9. Man müsste also (außerdem mit zwei [[ … ]], warum, erklärt Meillo bestimmt parallel bald :D )

Code: Alles auswählen

[[:digit:]][[:digit:]][[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]
schreiben, was gleich nicht mehr unbedingt kürzer ist.
grep kennt auch eine Angabe, wie oft sich ein Ausdruck wiederholen soll

Code: Alles auswählen

grep -E '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}'
aber auch da wäre [0-9], statt [[:digit:]] kürzer und wohl auch übersichtlicher.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destname_zbarimg()
{
	zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-
}
Lege Ziel fest->hier die Funktion (?) zbarimg
Wende zbarimg an auf den input, der von pdftoppm kommt. Verwende keinen Barcode->verwende code39 und gebe nur das Barcode-Ergebnis aus.
pdftoppm erzeugt ein PNG und wandelt nur die erste Seite in ein png.
Benutze (nach zbarimg???) einen TRENNER anstelle des Tabulators und nur für die Felder 2 (???)
Also gib nur die 2 gefundenen (Datum _ Variable) aus?
Wiederum eine Funktion, mit Namen „destname_zbarimg“, die diesmal (offensichtlich) zbarimg benutzt und wieder hauptsächlich die vorher im Thema ausprobierten Einzelschritte kombiniert. Die Optionen für zbarimg und pdftoppm sind einfach übernommen. Bei zbarimg explizit nur Code 39 zu aktivieren kann mögliche Falscherkennungen anderer Codes vorbeugen, denke ich.

Ich habe aber wieder einen „Trick“ benutzt, um keine temporäre, von pdftoppm produzierte PNG-Datei zu haben, die man löschen müsste. pdftoppm bekommt keinen Zieldateinamen übergeben – sondern nur die Quell-PDF-Datei in $1 – und schreibt sein Ergebnis (die Bits einer PNG-Datei) damit auf die Standardausgabe. Folgende Syntax sorgt dafür, dass die Bash (geht nur mit der) automatisch selbst dafür sorgt, dass diese Standardausgabe an zbarimg wie eine Datei übergeben wird:

Code: Alles auswählen

zbarimg … <(pdftoppm …)
Das erreicht das gleiche wie das, was du weiter oben schon mit einer temporären PNG-Datei ausprobiert hattest (leicht von mir umformatiert):
letzter3 hat geschrieben: ↑ zum Beitrag ↑
02.04.2022 14:06:11

Code: Alles auswählen

pdftoppm -png -singlefile some.pdf tmp
zbarimg -q -Scode39.enable tmp.png 

Die Ausgabe von zbarimg ist für die relevanten PDFs ja anscheinend
letzter3 hat geschrieben: ↑ zum Beitrag ↑
02.04.2022 14:06:11

Code: Alles auswählen

CODE-39:2022-03-24 20123988
Das

Code: Alles auswählen

… | cut -d: -f2-
sorgt am Ende nur dafür, dass das CODE-39: weggeschnitten wird. cut unterteilt die Zeile in einzelne Felder, als Trennzeichen (delimiter) wird : angegeben. Man hat also „CODE-39“ und „2022-03-24 20123988“ und möchte davon jetzt nur das 2. Feld haben: -f2-. Das Minus hinter der 2 war eigentlich überflüssig, es besagt „2. Feld und alle folgenden“ – es gibt ja keine weiteren.

Ergänzung: An der Stelle hab ich den Ursprungsbeitrag gerade noch ergänzt und ein

Code: Alles auswählen

… | tr ' ' _
angehängt. Das ersetzt das eine Leerzeichen im „2022-03-24 20123988“ durch den gewünschten Unterstrich.


letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

: "${method:=zbarimg}"
den : hab ich auf die Schnelle nur als "application" in der bash gefunden. Die englische Erklärung ist mir aber zu hoch. Setze incl. in der Methode (hier->zbarimg) verwendeten Variablen und führe aus? Würde dann mit dem destname korrespondieren.
Da war ich etwas übermütig :lol: und die method-Variable/-Auswahl an sich mag für dein Problem am Ende auch überflüssiug sein. Diese Zeile weist der Variablen den Standardwert „zbarimg“ zu, wenn die Variable noch ungesetzt/null oder leer ist. Lang – aber nicht 100% äquivalent! – ausgeschrieben:

Code: Alles auswählen

if [ -z "$method" ]; then
    method=zbarimg
fi
: ist ein Kommando, das einfach nichts macht, siehe help :. Kann man als Platzhalter oder zum Verwerfen von Dingen benutzen. Die Syntax

Code: Alles auswählen

${variable:=wert}
weist variable den Wert wert zu, wenn variable ungesetzt oder null ist. Das Konstrukt gibt allerdings den Wert von variable auch zurück, deshalb verwirft man ihn mit dem :.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

srcfile=$1
Quellfile (ohne Prüfung, ob das überhaupt ein PDF ist?)
Das $1 ist hier des erste Argument, das dem Skript übergeben wurde. Da das noch keine Komplettlösung sein sollte, hab ich da keine weitere Prüfung eingebaut. Aber hast recht, das sollte man sicher irgendwo noch machen.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destdir=${2:-/default/destination/dir}
Zielverzeichnis. Ist von mir zu setzen. Aber bei {2: steig ich aus.
Eine andere Variante für Standardwertzuweisung, wenn ungesetzt. Nur das hier der Inhalt des zweiten Skriptarguments, $2, angeguckt wird und wenn leer oder nicht angegeben der Vorgabewert /default/destination/dir der Variablen destdir zugewiesen wird. Anderfalls wird der Inhalt von $2 dem destdir zugewiesen. Du kannst das Skript also mit oder ohne aufrufen:

Code: Alles auswählen

~$ das_skript ein.pdf
~$ das_skript ein.pdf /der/zielordner
Hatte ich mehr zum Ausprobieren so geschrieben, am Ende reicht dir vielleicht

Code: Alles auswählen

destdir=/hier/oder/dort

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

destname=$("destname_$method" "$srcfile").pdf
Definition des künftigen Namens in Abhängigkeit der verwendeten Methode. Defaultmäßig also des outputs von cut -d: -f2-, nachdem zbarimg an dem Quellfile rumgewurschtelt hat.
Hier wird eine der beiden oben definierten Funktionen aufgerufen, abhängig von gesetzter method. Die Ausgabe beider Funktionen ist so zurechtgeschnitten, wie oben beschrieben, dass sie genau der gesuchte Zieldateiname ist, plus das hier noch angehängte .pdf.

Code: Alles auswählen

"destname_$method" "$srcfile"
ist wieder eine Abkürzung, um abhängig vom method-Inhalt die richtige Funktion aufzurufen. Ausgeschrieben wäre es:

Code: Alles auswählen

if [ "$method" = pdftotext ]; then
    destname_pdftotext "$srcfile"
elif ["$method" = zbarimg ]; then
    destname_zbarimg "$srcfile"
fi
Der Name eines aufzurufenden Kommandos kann nämlich auch einfach in einer Variablen stehen:

Code: Alles auswählen

#!/bin/sh
some_variable=less
$some_variable ~/.bashrc

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

echo "Would move '$(realpath "$srcfile")' to '${destdir%/}/${destname}'"
Schreibe auf den screen, was du tun würdest.
Ja, genau. Einfach zum Ausprobieren für dich (und mich vorher).
letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Aber wo kommt jetzt realpath her?
Das ist ein Kommando aus den Debiancoreutils. Es gibt dir zu einem Dateipfad den absoluten Pfad aus:

Code: Alles auswählen

~$ realpath Documents/some.pdf
/home/letzter3/Documents/some.pdf
War hier nur zu kosmetischen Zwecken verwendet.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29

Code: Alles auswählen

#mv -nv -- "$srcfile" "${destdir%/}/${destname}"
Auskommentiert wird das Quell-PDF verschoben in das Zielverzeichnis als PDF mit dem Namen der durch destname=$("destname_$method" "$srcfile").pdf festgelegt wurde.
Genau, # entfernen und das Verschieben würde, nach obigem echo, tatsächlich ausgeführt. Wenn ich keinen Quatsch gemacht hab, dann so wie du es in deinen Beiträgen beschrieben hast. (Gut, dass dir hier das ${destdir%/} nicht aufgefallen ist. Deshalb schreib ich jetzt auch nix mehr dazu :mrgreen: )

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Was mir noch nicht einleuchtet: wo liegt das script? Es wird ja kein Verzeichnis angegeben, in dem "gearbeitet" werden soll.
Was ich vielleicht mehr am Anfang meines Romans hier hätte schreiben sollen: Das Skript war erstmal nur als Zusammenfassung deiner und eggys Versuchsschritte vorher gedacht. Es fehlt – offensichtlich, hoffe ich – noch der automatisierte Aufruf durch inotify, cron oder den Hausmeister. Wenn ich mich richtig erinnere, sollte das Skript gelegentlich auch manuell aufgerufen werden (?) (grad keine Lust mehr, zu suchen …). Dann würde es sich anbieten, dieses Umbenennen so als eigenständiges Skript zu halten und das autmatisierte Aufrufen separat zu lösen – und dieses Skript dort heraus aufzurufen.

Aber zu der Frage: Du kannst es hinlegen, wo du möchtest. Temporäre Dateien sind vermieden, wie beschrieben (die landen also nicht irgendwo, da es keine gibt). Das Zielverzeichnis kann dem Skript übergeben oder fest definiert werden. Und an die PDF-Dateien kommt es heran, indem ihre Pfade sinnvoll übergeben werden. Wenn es also automatisiert aufgerufen würde, wären das sehr wahrscheinlich sowieso absolute Pfade:

Code: Alles auswählen

rename_from_barcode /some/samba/share/1970-01-01-00-00-00.pdf
rename_from_barcode wäre z.B. ein Name der sich anbietet. Ich würde das Skript wahrscheinlich nach /usr/local/bin tun, also /usr/local/bin/rename_from_barcode.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
07.04.2022 00:24:29
Kann
a) ein Log erzeugt werden, in dem stumpf die Umwandlung dokumentiert wird?
b) eine Warnmeldung per mailx bei Abbruch versandt werden?
Ja, ein Log wär nicht schwer. Man könnte einfach das echo nach /var/log/irgendwo umleiten oder logger benutzen. Mail verschicken ebenso, da kenn ich mich aber mit dem üblichen Werkzeugen nicht aus. Beides würde ich instinktiv und aus Erfahrung eher in der evtl. separaten Automatisierung machen, nicht hier direkt.

Wenn ich das so vorschlagen darf, du hattest ja geschrieben, dass du dich Ostern damit wieder beschäftigen willst: Du könntest ausprobieren, ob meine „Zusammenfassung“ die richtigen Zieldateinamen produziert, falls wichtig mit beiden Methoden.

So, Bierchen ist leer, das muss erstmal reichen :lol:
Manchmal bekannt als Just (another) Terminal Hacker.

eggy
Beiträge: 3331
Registriert: 10.05.2008 11:23:50

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von eggy » 15.04.2022 13:49:38

Da Meillos Kurs zur Vermeidung lokaler Keksanhäufung außer Konkurrenz läuft, geht der Erklärkeks der Woche diesmal wohl an JTH. :THX:

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 15.04.2022 17:05:24

:oops: :lol:
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von Meillo » 16.04.2022 07:56:26

Da mache ich doch gerne die Keksdose auf und ueberreiche dir einen DFDE-Keks:
Bild
Use ed once in a while!

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 17.04.2022 13:42:49

JTH hat geschrieben: ↑ zum Beitrag ↑
14.04.2022 22:19:39
Wenn ich das so vorschlagen darf, du hattest ja geschrieben, dass du dich Ostern damit wieder beschäftigen willst: Du könntest ausprobieren, ob meine „Zusammenfassung“ die richtigen Zieldateinamen produziert, falls wichtig mit beiden Methoden.
Hier die Ergebnisse der Standardfunktion:

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/default/destination/dir/2022-04-07_VR-789.pdf'
gesetztes DestDir

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
letzte # entfernt, DestDir ist nicht vorhanden

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
~/barcode mv: das Verschieben von '1.pdf' nach '/home/letzter/barcode/test/2022-04-07_VR-789.pdf' ist nicht möglich: Datei oder Verzeichnis nicht gefunden

Code: Alles auswählen

~/barcode mkdir test
~/barcode ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
Datei umbenannt '1.pdf' -> '/home/letzter/barcode/test/2022-04-07_VR-789.pdf'
~/barcode cd test
~/barcode/test ls
2022-04-07_VR-789.pdf
Fehler provozieren, 1.txt ist nicht vorhanden

Code: Alles auswählen

./rename_from_barcode.sh 1.txt
zsh: datei oder Verzeichnis nicht gefunden: ./rename_from_barcode.sh
Frage: Warum meldet sich hier zsh (ist gerade ein manjaro) und nicht die bash?

Fehler provozieren, kein Barcode im PDF, PDF ist aber vorhanden

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh ./rename_from_barcode.sh Unbenannt1.pdf
I/O Error: Couldn't open file 'Unbenannt1.pdf': No such file or directory.
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/737

Code: Alles auswählen

cat rename_from_barcode.sh
#!/bin/bash
set -eu -o pipefail

destname_pdftotext()
{
        pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}

destname_zbarimg()
{
        zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-  | tr ' ' _
}

: "${method:=zbarimg}"
srcfile=$1
destdir=${2:-/home/letzter/barcode/test}
destname=$("destname_$method" "$srcfile").pdf

echo "Would move '$(realpath "$srcfile")' to '${destdir%/}/${destname}'"
mv -nv -- "$srcfile" "${destdir%/}/${destname}"
Macht also erstmal, was es soll.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 17.04.2022 13:45:16

Und mit pdftotext

Code: Alles auswählen

Would move '/home/letzter/barcode/2.pdf' to '/home/letzter/barcode/test/2022-04-07_20123991.pdf'
Datei umbenannt '2.pdf' -> '/home/letzter/barcode/test/2022-04-07_20123991.pdf'
Also auch alles okay.

Wie kann ich die Ausführungszeit des scriptes messen?
Gefühlt ist pdftotext erheblich schneller
Zuletzt geändert von letzter3 am 17.04.2022 13:48:38, insgesamt 1-mal geändert.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 17.04.2022 13:47:48

Wie muss das script angepasst werden, damit es (ich bevorzuge mittlerweile nen cron-Job an statt inotify) samtliche PDFs im Verzeichnis bearbeitet?
Das händische Aufrufen (durch den Anwender per Button o.ä.) ist nicht notwendig.

Auf die Erläuterungen zum script gehe ich separat ein.
Vielen Dank für die viele Arbeit und Mühe!!!

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 17.04.2022 14:28:59

letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:45:16
Wie kann ich die Ausführungszeit des scriptes messen?
Gefühlt ist pdftotext erheblich schneller
zbarimg

Code: Alles auswählen

time ./rename_from_barcode.sh 1.pdf
Would move '/home/letzter/barcode/1.pdf' to '/home/letzter/barcode/test/2022-04-07_20123991.pdf'
./rename_from_barcode.sh 1.pdf  0,18s user 0,03s system 25% cpu 0,817 total
pdftotext

Code: Alles auswählen

time ./rename_from_barcode.sh 2.pdf   
Would move '/home/letzter/barcode/2.pdf' to '/home/letzter/barcode/test/2022-04-07_20123991.pdf'
./rename_from_barcode.sh 2.pdf  0,03s user 0,01s system 122% cpu 0,027 total
Arbeitet pdftotext mit mehreren Kern und zbarimg nur mit einem?

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 17.04.2022 19:05:33

letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:42:49
letzte # entfernt, DestDir ist nicht vorhanden
[code
~/barcode mv: das Verschieben von '1.pdf' nach '/home/letzter/barcode/test/2022-04-07_VR-789.pdf' ist nicht möglich: Datei oder Verzeichnis nicht gefunden[/code]
Ups, mein Fehler. Das mkdir hatte ich vergessen. Am Besten wäre ein

Code: Alles auswählen

mkdir -p "$destdir"
direkt vor dem abschließenden Verschiebungsschritt, falls auch eins oder mehrere der Elternverzeichnisse noch nicht existieren.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:42:49

Code: Alles auswählen

./rename_from_barcode.sh 1.txt
zsh: datei oder Verzeichnis nicht gefunden: ./rename_from_barcode.sh
Frage: Warum meldet sich hier zsh (ist gerade ein manjaro) und nicht die bash?
Das deutet daraufhin, dass du nicht in dem Ordner warst, in dem das Skript lag. Die zsh beschwert sich, dass es den Pfad ./rename_from_barcode.sh nicht gefunden hat. Die Meldung kommt von der interaktiven Shell, aus der heraus du versuchst, es aufzurufen. Und ist hier unabhängig von der verwendeten *sh.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:42:49
Fehler provozieren, kein Barcode im PDF, PDF ist aber vorhanden

Code: Alles auswählen

~/barcode ./rename_from_barcode.sh ./rename_from_barcode.sh Unbenannt1.pdf
I/O Error: Couldn't open file 'Unbenannt1.pdf': No such file or directory.
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/737
Und es kommt vor allem kein „Would move das.pdf to Murks“. Das ist gut.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:45:16
Wie kann ich die Ausführungszeit des scriptes messen?
Gefühlt ist pdftotext erheblich schneller
time hast du ja gefunden. Dass pdftotext schneller ist, ist zu erwarten. Es extrahiert ja einfach den Plain-Text, der so direkt im PDF enthalten ist und wirft alle „Formatierung“ drum herum weg. Das ’ne triviale Aufgabe.

zbarimg auf der anderen Seite benutzt Bildverarbeitung/-erkennung, um die Strichcodes zu finden. Das ist eine aufwändigere und wahrscheinlich fehleranfälligere Vorgehensweise. Allerdings kann die auch dann noch funktionieren, wenn der Code im PDF nicht als „Text“ vorliegt.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:47:48
Wie muss das script angepasst werden, damit es (ich bevorzuge mittlerweile nen cron-Job an statt inotify) samtliche PDFs im Verzeichnis bearbeitet?
Wär es einfach ein Ordner, in dem die PDFs ohne weitere Unterordner liegen? Dann geht das einfach mit einer Schleife und das Ganze dann („modern“) mit einem systemd-Timer oder eben (bewährten) Cronjob aufgerufen. Ist garantiert, dass in dem Moment (nachts etwa) wo die Umbenennung laufen könnte, keine neuen PDFs dazukommen können? inotify wär bestimmt spannender, von der Umsetzung noch ein klein bisschen (nix riesiges) mehr Bastelei :D
Manchmal bekannt als Just (another) Terminal Hacker.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 18.04.2022 02:53:08

JTH hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 19:05:33
letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:42:49
letzte # entfernt, DestDir ist nicht vorhanden
[code
~/barcode mv: das Verschieben von '1.pdf' nach '/home/letzter/barcode/test/2022-04-07_VR-789.pdf' ist nicht möglich: Datei oder Verzeichnis nicht gefunden[/code]
Ups, mein Fehler. Das mkdir hatte ich vergessen. Am Besten wäre ein

Code: Alles auswählen

mkdir -p "$destdir"
direkt vor dem abschließenden Verschiebungsschritt, falls auch eins oder mehrere der Elternverzeichnisse noch nicht existieren.
Nun, im Anwendungsfall kein Problem, da ich ja die entsprechenden Ordner definiere.
Und besser, es gibt nen Fehler, als das im Fehlerfall irgendwo ein Verzeichnis angelegt wird, welches danach nicht vom Backupscript erfasst ist.
JTH hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 19:05:33
letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:42:49

Code: Alles auswählen

./rename_from_barcode.sh 1.txt
zsh: datei oder Verzeichnis nicht gefunden: ./rename_from_barcode.sh
Frage: Warum meldet sich hier zsh (ist gerade ein manjaro) und nicht die bash?
Das deutet daraufhin, dass du nicht in dem Ordner warst, in dem das Skript lag. Die zsh beschwert sich, dass es den Pfad ./rename_from_barcode.sh nicht gefunden hat. Die Meldung kommt von der interaktiven Shell, aus der heraus du versuchst, es aufzurufen. Und ist hier unabhängig von der verwendeten *sh.
Jupp. Verstanden.
Hier nochmal (nur zur Vollständigkeit) der versuch, ein NICHT-PDF zu scannen.

Code: Alles auswählen

./rename_from_barcode.sh mnt-MSc_Daten.automount
Syntax Warning: May not be a PDF file (continuing anyway)
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/737
JTH hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 19:05:33
time hast du ja gefunden. Dass pdftotext schneller ist, ist zu erwarten. Es extrahiert ja einfach den Plain-Text, der so direkt im PDF enthalten ist und wirft alle „Formatierung“ drum herum weg. Das ’ne triviale Aufgabe.

zbarimg auf der anderen Seite benutzt Bildverarbeitung/-erkennung, um die Strichcodes zu finden. Das ist eine aufwändigere und wahrscheinlich fehleranfälligere Vorgehensweise. Allerdings kann die auch dann noch funktionieren, wenn der Code im PDF nicht als „Text“ vorliegt.
Das leuchtet mir ein. Auf den Gedanken mit den Kernen bin ich gekommen, wegen 122% cpu
Das deutete mir auf mehr als 1 Kern hin.
JTH hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 19:05:33
letzter3 hat geschrieben: ↑ zum Beitrag ↑
17.04.2022 13:47:48
Wie muss das script angepasst werden, damit es (ich bevorzuge mittlerweile nen cron-Job an statt inotify) samtliche PDFs im Verzeichnis bearbeitet?
Wär es einfach ein Ordner, in dem die PDFs ohne weitere Unterordner liegen? Dann geht das einfach mit einer Schleife und das Ganze dann („modern“) mit einem systemd-Timer oder eben (bewährten) Cronjob aufgerufen. Ist garantiert, dass in dem Moment (nachts etwa) wo die Umbenennung laufen könnte, keine neuen PDFs dazukommen können? inotify wär bestimmt spannender, von der Umsetzung noch ein klein bisschen (nix riesiges) mehr Bastelei :D
Das Quellverzeichnis ist ein Ordner ohne Unterverzeichnisse.
Das Zielverzeichnis ebendso.
Es sollte die Regel sein, das niemand zur Zeit eines cron dort Dateien reinspielt. 100% ausgeschlossen werden kann das jedoch nicht.
Es spricht nichts dagegen, sowohl die zeitgesteuerte Variante als auch inotify zu testen.
Die Frage bei zeitgesteuert: besteht die Möglichkeit, dass sich das script "irgendwie" aufhängt? Und das dann ggf. Dateien nicht umbenannt werden?

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 18.04.2022 19:49:36

letzter3 hat geschrieben: ↑ zum Beitrag ↑
18.04.2022 02:53:08
Und besser, es gibt nen Fehler, als das im Fehlerfall irgendwo ein Verzeichnis angelegt wird, welches danach nicht vom Backupscript erfasst ist.
Okay, klar, wenns zum Anwendungsfall passt, kann man das Ordneranlegen natürlich weglassen.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
18.04.2022 02:53:08
Die Frage bei zeitgesteuert: besteht die Möglichkeit, dass sich das script "irgendwie" aufhängt? Und das dann ggf. Dateien nicht umbenannt werden?
Das kann höchstens passieren, wenn eines der drei zum Konvertieren benutzten Programme zbarimg, pdftotext oder pdftoppm (in einer Endlosschleife) hängen bleibt. Wäre dann ein Bug in diesen. Halte ich aber für eher unwahrscheinlich. Wenn es allerdings auftritt, wäre das auch bei einer inotify-getriggerten Variante möglich.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
18.04.2022 02:53:08
Es spricht nichts dagegen, sowohl die zeitgesteuerte Variante als auch inotify zu testen.
Ich hab dann einfach mal, als nächsten Schritt zum Ausprobieren und Nachvollziehen, ein Grundgerüst mit Debianinotify-tools für dich:

Code: Alles auswählen

#!/bin/bash

watched_dir=/hier/dort/irgendwo

inotifywait -e close_write -e moved_to --format '%w%f' -m "$watched_dir" | while read -r filename; do
	if [[ ! "${filename##*/}" =~ ^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]\.pdf$ ]]; then
		# Ignoriere Dateien (temporäre von Samba z.B.), auf die nicht das
		# Muster yyyy-mm-dd-hh-mm-ss.pdf passt.
		echo "Ignoring “$filename”" >&2
		continue
	fi

	echo "Processing “$filename”" >&2
	rename_from_barcode "$filename"
done
Das würde nun auch Dateien ignorieren, auf die nicht das im Eingangsbeitrag erwähnte Muster yyyy-mm-dd-hh-mm-ss.pdf passt.
Den Aufruf rename_from_barcode müsstest du bei Bedarf mit absolutem/relativen Pfad anpassen, je nach dem wo das Skript bei dir liegt (wenn es nicht im PATH liegt).

Ich weiß allerdings nicht und hab gerade nicht ausprobiert, ob Samba evtl. noch Zusätzliches, wie Dateiattribute ändern, nachträglich macht, wenn man eine Datei auf einen Share schiebt. Um das zu betrachten könntest du Folgendes

Code: Alles auswählen

inotifywait -m /das/zu/beobachtende/verzeichnis
mal auf deinem Samba-Server laufen lassen und hier posten, was beim Draufschieben eines PDFs ausgegeben wird. Mit anonymisierten Pfaden natürlich, wenn notwendig.

Passiert das Umbenennen/Verschieben der PDFs auf dem Server innerhalb der selben Partition/im selben Dateisystem? Wäre relevant dafür, wie sicher es gegen ungewollte/unterwartete Unterbrechungen ist.
Manchmal bekannt als Just (another) Terminal Hacker.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 20.04.2022 21:49:51

Nur kurze Pause wegen hauptberuflicher Inanspruchnahme....

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 23.04.2022 14:06:32

Habe die Prüfbedingung mal so geändert, das nur YYYY-MM-DD geprüft wird, also ohne mm-ss.
Anscheinend habe ich das aber nicht richtig gemacht, finde aber den Fehler nicht.
Habe "nur" die letzten 4 "[0-9]" entfernt.

Code: Alles auswählen

#!/bin/bash

watched_dir=/home/letzter/barcode/test

inotifywait -e close_write -e moved_to --format '%w%f' -m "$watched_dir" | while read -r filename; do
	if [[ ! "${filename##*/}" =~ ^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]\.pdf$ ]]; then
		# Ignoriere Dateien (temporäre von Samba z.B.), auf die nicht das
		# Muster yyyy-mm-dd-hh-.pdf passt.
		echo "Ignoring “$filename”" >&2
		continue
	fi

	echo "Processing “$filename”" >&2
	rename_from_barcode "$filename"
done

Code: Alles auswählen

~/barcode ./inotify.sh
Setting up watches.
Watches established.
Ignoring “/home/letzter/barcode/test/2022-04-07.pdf”
^C
~/barcode
Okay, sehe schon. Ist noch einmal "[0-9]" zu viel drin.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 23.04.2022 14:13:31

Weiter gehts.

Code: Alles auswählen

#!/bin/bash

watched_dir=/home/letzter/barcode/test

inotifywait -e close_write -e moved_to --format '%w%f' -m "$watched_dir" | while read -r filename; do
	if [[ ! "${filename##*/}" =~ ^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\.pdf$ ]]; then
		# Ignoriere Dateien (temporäre von Samba z.B.), auf die nicht das
		# Muster yyyy-mm-dd-hh-.pdf passt.
		echo "Ignoring “$filename”" >&2
		continue
	fi

	echo "Processing “$filename”" >&2
	/home/letzter/barcode/rename_from_barcode.sh "$filename"
done

Code: Alles auswählen

~/barcode ./inotify.sh
Setting up watches.
Watches established.
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Would move '/home/letzter/barcode/test/2022-04-07.pdf' to '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
Datei umbenannt '/home/letzter/barcode/test/2022-04-07.pdf' -> '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
Processing “/home/letzter/barcode/test/2022-04-08.pdf”
Would move '/home/letzter/barcode/test/2022-04-08.pdf' to '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
^C
Funktioniert also erstmal.
Die richtig umbenannten Dateien werden /home/letzter/barcode/test1 verschoben.
Muss gleich mal ein paar Sachen testen......

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 23.04.2022 14:39:45

Nun auf dem Server direkt.
Ich befinde mich dort als user letzter in meinem home-Verzeichnis, auf welches ich per smb in konquerer zugreife.

Code: Alles auswählen

letzter@ptLWL01:~/barcode$ ./inotify.sh
Setting up watches.
Watches established.
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Document stream is empty
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Would move '/home/letzter/barcode/test/2022-04-07.pdf' to '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
Datei umbenannt '/home/letzter/barcode/test/2022-04-07.pdf' -> '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
^C
letzter@ptLWL01:~/barcode$ 
Die Ausgabe

Code: Alles auswählen

Would move '/home/letzter/barcode/test/2022-04-07.pdf' to '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
Datei umbenannt '/home/letzter/barcode/test/2022-04-07.pdf' -> '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
ist leider falsch. Zwar wird home//letzter/barcode/test1/2022-04-07_20123991.pdf erzeugt, aber /home/letzter/barcode/test/2022-04-07.pdf nicht gelöscht.
edit: Wohl n cache-Fehler im Konqueror. Datei wird verschoben.

Code: Alles auswählen

inotifywait -m 

/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ OPEN,ISDIR 
/home/letzter/barcode/test/ ACCESS,ISDIR 
/home/letzter/barcode/test/ CLOSE_NOWRITE,CLOSE,ISDIR 
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ OPEN 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ CLOSE_NOWRITE,CLOSE 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf

/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ OPEN 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ CLOSE_NOWRITE,CLOSE 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf

/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ OPEN 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ CLOSE_NOWRITE,CLOSE 2022-04-07.pdf
/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf

/home/letzter/barcode/test/ ACCESS 2022-04-07.pdf
/home/letzter/barcode/test/ CLOSE_NOWRITE,CLOSE 2022-04-07.pdf
/home/letzter/barcode/test/ MOVED_FROM 2022-04-07.pdf
^C
letzter@ptLWL01:~$ 
Das /home/letzter/barcode/test/ ACCESS 2022-04-07.pdf taucht ungezählt tausende male auf.
Die Ausgaben gehen über die Terminallänge hinaus. Bei Bedarf leite ich das ganze nochmal um, um auch den Anfang der Ausgabe zu sehen.
Passiert das Umbenennen/Verschieben der PDFs auf dem Server innerhalb der selben Partition/im selben Dateisystem? Wäre relevant dafür, wie sicher es gegen ungewollte/unterwartete Unterbrechungen ist.
Ja.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 23.04.2022 14:49:52

Ohne smb (also per ssh auf dem Server) geht es fluffig.

Code: Alles auswählen

letzter@ptLWL01:~/barcode$ ./inotify.sh
Setting up watches.
Watches established.
Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Would move '/home/letzter/barcode/test/2022-04-07.pdf' to '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
Datei umbenannt '/home/letzter/barcode/test/2022-04-07.pdf' -> '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
^C
letzter@ptLWL01:~/barcode$ 
Und die inotify-Überwachung
NoPaste-Eintrag41654

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 23.04.2022 15:40:58

Also wäre es wohl am einfachsten, das ganze per cron zu erledigen.
Wie müsste das rename_from_barcode aussehen, um crontauglich
  • nur pdf's zu behandeln (keine weitere Prüfung, ggf. will ich ja auch mal per Hand eine Rechnung.pdf in den Ordner schmeissen)
  • alle pdf's im Ordner zu behandeln
  • ein "dummes" log zu erstellen
  • bei Fehlern eine mail zu verschicken (es kann der user "letzter" dazu verwendet werden)

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 26.04.2022 19:47:18

letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:06:32
Okay, sehe schon. Ist noch einmal "[0-9]" zu viel drin.
Jop, das wars.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:06:32
Passiert das Umbenennen/Verschieben der PDFs auf dem Server innerhalb der selben Partition/im selben Dateisystem? Wäre relevant dafür, wie sicher es gegen ungewollte/unterwartete Unterbrechungen ist.
Ja.
Das ist schon mal gut. Ist außerdem (k)eine Verschlüsselung im Spiel?

letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:49:52
Und die inotify-Überwachung
NoPaste-Eintrag41654
Dort hast du per Samba-Share ein PDF auf den Server kopiert? Oder, wie im selben Beitrag angedeutet, innerhalb einer SSH-Session direkt auf dem Server eine Datei kopiert?

Ich hab das Szenario (Datei auf einen Samba-Share kopieren und auf dem Samba-Server das Share-Verzeichnis mit meinem obigem Skript überwachen) mal selbst nachgestellt. Die Ereignisse von inotifywait -m sahen sinngemäß so aus, wie in deinem Nopaste NoPaste-Eintrag41654. Und das Umbenennen funktionierte tatsächlich auch ohne die bei dir (etwas überraschend) aufgetretenen, mehrfachen Fehlversuche (siehe folgende Absätze).

Die vielen ACCESS-Einträge entstehen, wenn eine Datei (das auslösende PDF) Schritt für Schritt gelesen wird (durch pdftotext oder zbarimg). Machen den Mitschnitt etwas unübersichtlich, aber sind so korrekt.


Im Folgenden wurde anscheinend mehrfach versucht, das PDF schon zu lesen, bevor es (vollständig) geschrieben wurde.
letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:39:45

Code: Alles auswählen

Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Document stream is empty
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Hier ist die Datei noch (fast) komplett leer – „is empty“.
letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:39:45

Code: Alles auswählen

Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Hier scheint sie schon Daten zu enthalten, aber noch nicht vollständig (als PDF interpretierbar) zu sein.

Es wundert mich etwas, dass beide obigen Fälle auftreten. Deinem Mitschnitt von inotifywait -m nach (und meinem Nachstellen, soweit möglich) kann dieser mehrfache Versuch gar nicht auftreten, weil es für das PDF nur ein einziges CLOSE_WRITE-Ereignis gibt. Und das Skript wartet nur auf CLOSE_WRITE und MOVED_TO, letzteres tritt anscheinend gar nicht auf. Die Dutzenden anderen Ereignisse werden nicht beachtet, können also nicht zu einem zu frühen Verschiebeversuch führen.

Deshalb nochmal blöd gefragt: In welchem genauen Szenario traten diese Fehlversuche auf? Der inotifywait-Mitschnitt aus den Nopaste gehört, so wie er aussieht, nicht dazu?!
letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:39:45

Code: Alles auswählen

Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Would move '/home/letzter/barcode/test/2022-04-07.pdf' to '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
Datei umbenannt '/home/letzter/barcode/test/2022-04-07.pdf' -> '/home/letzter/barcode/test1/2022-04-07_20123991.pdf'
Letztendlich hat das Verschieben nach den mehrfachen zu frühen Versuchen hier ja funktioniert. Wenn man die Fehlversuche abstellen kann, würde die Lösung also funktionieren. Man könnte sie auch nicht beachten und hinnehmen, das würde aber die geplante Mail bei Fehlern fälschlich auslösen.

Ich würd gern noch nen Moment schauen, ob das mit inotifywait hinzubekommen ist, wenn du noch Geduld hast ;) Wenn du die nicht hast, ist eine periodisch laufende Lösung alternativ schnell gemacht.


letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 15:40:58
  • ein "dummes" log zu erstellen
Wenn dir das reicht (?), könnte man bei beiden Lösungsansätzen sich dafür einfach auf systemds Journal verlassen, ohne von Hand in eine Datei nach /var/log o.ä. zu schreiben. Dazu müsst man einfach Ausgaben mit echo etc. machen, wie es rename_from_barcode oben schon macht. Das Log wäre dann später – nur beispielhaft – mit

Code: Alles auswählen

journalctl -u move-pdfs.service
lesbar.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 15:40:58
  • bei Fehlern eine mail zu verschicken (es kann der user "letzter" dazu verwendet werden)
Mit sendmail u.a. hab ich noch keinen rechten Kontakt gehabt. Ist auf dem Server denn schon ein MTA konfiguriert und in Benutzung? Vielleicht springt hier an der Stelle – wenn es soweit ist – nochmal jemand anderes ein :)
Manchmal bekannt als Just (another) Terminal Hacker.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 26.04.2022 21:21:08

JTH hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 19:47:18
letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:06:32
Passiert das Umbenennen/Verschieben der PDFs auf dem Server innerhalb der selben Partition/im selben Dateisystem? Wäre relevant dafür, wie sicher es gegen ungewollte/unterwartete Unterbrechungen ist.
Ja.
Das ist schon mal gut. Ist außerdem (k)eine Verschlüsselung im Spiel?
Nein, keine Verschlüsselung
JTH hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 19:47:18
letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:49:52
Und die inotify-Überwachung
NoPaste-Eintrag41654
Dort hast du per Samba-Share ein PDF auf den Server kopiert? Oder, wie im selben Beitrag angedeutet, innerhalb einer SSH-Session direkt auf dem Server eine Datei kopiert?
Das war direkt per ssh.
Hier ist die mittels VPN -> smb [von mir zu Hause (Manjaro) auf den extern stehenden server]
NoPaste-Eintrag41660
Seltsamerweise keine Fehler mehr.
JTH hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 19:47:18
Im Folgenden wurde anscheinend mehrfach versucht, das PDF schon zu lesen, bevor es (vollständig) geschrieben wurde.
letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:39:45

Code: Alles auswählen

Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Document stream is empty
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Hier ist die Datei noch (fast) komplett leer – „is empty“.
letzter3 hat geschrieben: ↑ zum Beitrag ↑
23.04.2022 14:39:45

Code: Alles auswählen

Processing “/home/letzter/barcode/test/2022-04-07.pdf”
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
ERROR: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575
Hier scheint sie schon Daten zu enthalten, aber noch nicht vollständig (als PDF interpretierbar) zu sein.

Es wundert mich etwas, dass beide obigen Fälle auftreten. Deinem Mitschnitt von inotifywait -m nach (und meinem Nachstellen, soweit möglich) kann dieser mehrfache Versuch gar nicht auftreten, weil es für das PDF nur ein einziges CLOSE_WRITE-Ereignis gibt. Und das Skript wartet nur auf CLOSE_WRITE und MOVED_TO, letzteres tritt anscheinend gar nicht auf. Die Dutzenden anderen Ereignisse werden nicht beachtet, können also nicht zu einem zu frühen Verschiebeversuch führen.
Ggf. zur Sicherheit ein kurzes wait einfügen?
JTH hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 19:47:18
Deshalb nochmal blöd gefragt: In welchem genauen Szenario traten diese Fehlversuche auf? Der inotifywait-Mitschnitt aus den Nopaste gehört, so wie er aussieht, nicht dazu?!
Kopieren per smb, welches über einen VPN eingehängt ist. Der inotify von nopaste gehört nicht dazu.
JTH hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 19:47:18

Wenn dir das reicht (?), könnte man bei beiden Lösungsansätzen sich dafür einfach auf systemds Journal verlassen, ohne von Hand in eine Datei nach /var/log o.ä. zu schreiben. Dazu müsst man einfach Ausgaben mit echo etc. machen, wie es rename_from_barcode oben schon macht. Das Log wäre dann später – nur beispielhaft – mit

Code: Alles auswählen

journalctl -u move-pdfs.service
lesbar.
Mir wäre ein Klartext-Log an einem definierbaren Ort lieber.
JTH hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 19:47:18

Mit sendmail u.a. hab ich noch keinen rechten Kontakt gehabt. Ist auf dem Server denn schon ein MTA konfiguriert und in Benutzung? Vielleicht springt hier an der Stelle – wenn es soweit ist – nochmal jemand anderes ein :)
Ja, es gibt einen konfigurierten MTA für Fehlermeldungen
Hier das snippet von rkhunter.

Code: Alles auswählen

MAIL-ON-WARNING="letzter"

#
# Specify the mail command to use if MAIL-ON-WARNING is set.
# NOTE: Double quotes are not required around the command, but
# are required around the subject line if it contains spaces.
#
MAIL_CMD=mail -s "[rkhunter] Warnings found for ${HOST_NAME}"
Zuletzt geändert von JTH am 27.04.2022 16:18:24, insgesamt 1-mal geändert.
Grund: [quote] repariert

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 27.04.2022 17:51:02

letzter3 hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 21:21:08
Hier ist die mittels VPN -> smb [von mir zu Hause (Manjaro) auf den extern stehenden server]
NoPaste-Eintrag41660
Seltsamerweise keine Fehler mehr.
Hmm, okay. Das sieht aus, wie erwartet. Wenn du die Fehlversuche dann tatsächlich nur einmal beobachtet hast, behaupte ich einfach mal, dass das eine Unregelmäßigkeit war und dass die Umbenennung mit der Überwachung prinzipiell funktioniert – solange, bis es womöglich doch wiederholt auftritt.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 21:21:08
Ggf. zur Sicherheit ein kurzes wait einfügen?
Ja, das könnte man in der Zeile direkt über dem rename_from_barcode-Aufruf wohl machen, sleep 1 o.ä. Ist aber regelmäßig keine Problemlösung, sondern nur ein Verstecken. Bis das – vielleicht hier ja auch gar nicht wirklich existierende – Problem durch zusätzliche Verzögerung bei der Netzwerkübertragung oder so doch wieder mal auftritt.

Oder aber traten diese Fehlversuche in dem Prozess auf, wie du ihn im ersten Beitrag beschrieben hast?
letzter3 hat geschrieben: ↑ zum Beitrag ↑
31.03.2022 01:27:26
Es existiert eine Windowssoftware, welche zum Drucken von Rechnungen, Mahnungen etc. OpenOffice verwendet.
Als Drucker habe ich einen virtuellen PDF-Printer eingerichtet, welcher ein (durchsuchbares) PDF erzeugt und dieses danach auf den physikalischen Drucker schickt.
[…]
Der Ablageort der PDFs ist ein smb-share eines Debian (Debian 5.10.92-1 (2022-01-18) x86_64 GNU/Linux).
Schreiben die beteiligten Programme womöglich mehrfach ins PDF? Dann müsst man über diesen Ansatz doch nochmal nachdenken.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 21:21:08
Mir wäre ein Klartext-Log an einem definierbaren Ort lieber.
Wie sie wünschen :wink:

letzter3 hat geschrieben: ↑ zum Beitrag ↑
26.04.2022 21:21:08
Ja, es gibt einen konfigurierten MTA für Fehlermeldungen
Hier das snippet von rkhunter.
K. Keine Garantie, dass ich da irgendetwas sinnvolles mit anstelle.

Hier nochmal alles zusammengefasst, aufgeräumt und um einen systemd-Service ergänzt:

rename_from_barcode:

Code: Alles auswählen

#!/bin/bash
set -eu -o pipefail

destname_pdftotext()
{
	pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}

destname_zbarimg()
{
	zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-  | tr ' ' _
}

: "${method:=zbarimg}"
srcfile=$1
destdir=/heute/hier/morgen/dort
destname=$("destname_$method" "$srcfile").pdf

mv -nv -- "$srcfile" "${destdir%/}/${destname}"

watch_pdf_dir:

Code: Alles auswählen

#!/bin/bash
set -u

log()
{
    printf "%(%c)T: %s" -1 "$*"
}

watched_dir=/ueber/den/wolken

inotifywait -e close_write -e moved_to --format '%w%f' -mq "$watched_dir" | while read -r filename; do
	basename=${filename##*/}
	if [[ ! $basename =~ ^[^.].*\.pdf$ ]]; then
		# Ignoriere zumindest versteckte und Nicht-PDF-Dateien
		continue
	fi

	subject=
	if ! output="$(rename_from_barcode "$filename" 2>&1)"; then
		subject="Failed to move '$basename'"
		mail -s "$subject" letzter <<<"$output"
	fi
	log "$subject${subject:+: }$output"
done
Edit: Habe hier noch Zeitstempel ergänzt.

watch-pdf-dir.service

Code: Alles auswählen

[Unit]
Description=Watch PDF directory
Before=smbd.service

[Service]
ExecStart=/usr/local/bin/watch_pdf_dir
StandardOutput=append:/var/log/watch-pdf-dir.log
StandardError=inherit

[Install]
WantedBy=multi-user.target
Abzulegen als /etc/systemd/system/watch-pdf-dir.service und aktivieren mit systemctl enable watch-pdf-dir.service.

Eine Frage wär noch: Welchem User gehören die Dateien im Quell- und Zielverzeichnis oder welchem sollen sie gehören? Ein und demselben? Falls nicht, müsste man das noch mit beachten.

Der Pfad der Logdatei ist hier drüber im Service in der StandardOutput-Zeile festgelegt und anpassbar.

Als Bonus noch ein Schnipsel, der einmalig die gerade dort liegenden PDFs aus einem Ordner umbenennt:

Code: Alles auswählen

#!/bin/sh
set -u

srcdir=$1

for pdffile in "$srcdir/"*.pdf; do
	# Wenn kein PDF existiert, enthält $pdffile den String "$srcdir/*.pdf",
	# inklusive des Sternchens. In dem Fall wollen wir nicht versuchen, die
	# nicht existierende Datei umzubenennen: 
	[ -f "$pdffile" ] || continue

	if ! output="$(rename_from_barcode "$pdffile" 2>&1)"; then
		echo "Failed to move '$pdffile':"
	fi
	echo "$output"
done
Könnte man optional beim Start des Services einmal ausführen, um Nachzügler zu verschieben. Oder das könnte man so direkt auch für den periodischen Ansatz benutzen.
Zuletzt geändert von JTH am 27.04.2022 20:11:41, insgesamt 1-mal geändert.
Grund: Ausgaben von watch_pdf_dir um Zeitstempel ergänzt
Manchmal bekannt als Just (another) Terminal Hacker.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 27.04.2022 21:31:28

JTH hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 17:51:02
Oder aber traten diese Fehlversuche in dem Prozess auf, wie du ihn im ersten Beitrag beschrieben hast?
letzter3 hat geschrieben: ↑ zum Beitrag ↑
31.03.2022 01:27:26
Es existiert eine Windowssoftware, welche zum Drucken von Rechnungen, Mahnungen etc. OpenOffice verwendet.
Als Drucker habe ich einen virtuellen PDF-Printer eingerichtet, welcher ein (durchsuchbares) PDF erzeugt und dieses danach auf den physikalischen Drucker schickt.
[…]
Der Ablageort der PDFs ist ein smb-share eines Debian (Debian 5.10.92-1 (2022-01-18) x86_64 GNU/Linux).
Schreiben die beteiligten Programme womöglich mehrfach ins PDF? Dann müsst man über diesen Ansatz doch nochmal nachdenken.
Nein. Aber es war ein aufwendigeres PDF (eine Privatrechnung, da geben wir uns mehr Mühe) und da hat wohl einfach der Kopiervorgang etwas länger gedauert.
Aber: Ggf. wird das auch auftreten, wenn ein Privatrechnung wie oben beschrieben erzeugt wird. Kann ich gerade nicht prüfen.
JTH hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 17:51:02
Hier nochmal alles zusammengefasst, aufgeräumt und um einen systemd-Service ergänzt:

rename_from_barcode:

Code: Alles auswählen

#!/bin/bash
set -eu -o pipefail

destname_pdftotext()
{
	pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}

destname_zbarimg()
{
	zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-  | tr ' ' _
}

: "${method:=zbarimg}"
srcfile=$1
destdir=/heute/hier/morgen/dort
destname=$("destname_$method" "$srcfile").pdf

mv -nv -- "$srcfile" "${destdir%/}/${destname}"

Code: Alles auswählen

destdir=/heute/hier/morgen/dort
enthält kein $(".... Ist das nicht notwendig?
JTH hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 17:51:02
Eine Frage wär noch: Welchem User gehören die Dateien im Quell- und Zielverzeichnis oder welchem sollen sie gehören? Ein und demselben? Falls nicht, müsste man das noch mit beachten.
Ein und derselbe User.
JTH hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 17:51:02
Als Bonus noch ein Schnipsel, der einmalig die gerade dort liegenden PDFs aus einem Ordner umbenennt:

Code: Alles auswählen

#!/bin/sh
set -u

srcdir=$1

for pdffile in "$srcdir/"*.pdf; do
	# Wenn kein PDF existiert, enthält $pdffile den String "$srcdir/*.pdf",
	# inklusive des Sternchens. In dem Fall wollen wir nicht versuchen, die
	# nicht existierende Datei umzubenennen: 
	[ -f "$pdffile" ] || continue

	if ! output="$(rename_from_barcode "$pdffile" 2>&1)"; then
		echo "Failed to move '$pdffile':"
	fi
	echo "$output"
done
Könnte man optional beim Start des Services einmal ausführen, um Nachzügler zu verschieben. Oder das könnte man so direkt auch für den periodischen Ansatz benutzen.
liegt direkt im Verzeichnis mit den umzubenennenden PDFs.

Code: Alles auswählen

letzter@ptLWL01:~/barcode/test$ ./crony_.sh
./crony_.sh: 4: 1: parameter not set
letzter@ptLWL01:~/barcode/test$ 
Und nu :?:

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 27.04.2022 23:08:21

letzter3 hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 21:31:28
Nein. Aber es war ein aufwendigeres PDF (eine Privatrechnung, da geben wir uns mehr Mühe) und da hat wohl einfach der Kopiervorgang etwas länger gedauert.
Aber: Ggf. wird das auch auftreten, wenn ein Privatrechnung wie oben beschrieben erzeugt wird. Kann ich gerade nicht prüfen.
Rein durch einen längeren Kopiervorgang können diese mehreren Umbenennungsversuche nicht auftreten. Es muss dabei auch mehrfach ein CLOSE_WRITE-Ereignis per inotify vorkommen. Es könnte sein, dass Samba das (das meint: die Datei mehrfach open() und close()n) bei größeren Dateien macht – aber so riesig wird das PDF ja nun auch nicht gewesen sein und richtig glauben tu ich’s auch nicht.

Aber ja, das stimmt natürlich, wenn du Pech hast, taucht es beim nächsten gleichartigem PDF nochmal auf. Müsste man dann nochmal draufschauen. Du solltest, wenn es soweit ist, dazu ja Mails bekommen.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 21:31:28

Code: Alles auswählen

destdir=/heute/hier/morgen/dort
enthält kein $(".... Ist das nicht notwendig?
Nein, ist es nicht. Ich hatte die destdir=-Zeile ursprünglich etwas „komplizierter“ geschrieben, damit man das Skript auf zwei Arten aufrufen konnte:

Code: Alles auswählen

destdir=${2:-/standard/ziel/verzeichnis}

~$ rename_from_barcode irgendein.pdf                           # Benutzt /standard/ziel/verzeichnis
~$ rename_from_barcode irgendein.pdf /anderes/ziel/verzeichnis
Nachdem das für deine Anwendung anscheinend nicht notwendig ist, kann man dort jetzt einfach fix das Zielverzeichnis festlegen und sich das zweite Argument beim Aufruf sparen.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 21:31:28
Ein und derselbe User.
Das ist gut, dann muss man bei dem watch-pdf-dir.service oben nichts weiter beachten. Man könnte den Service sogar noch weiter einschränken, so dass das Skript im Hintergrund nur mit den Rechten des Benutzers läuft, dem die Dateien gehören. Muss aber nicht.

letzter3 hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 21:31:28
JTH hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 17:51:02

Code: Alles auswählen

[…]
srcdir=$1
[…]
[…]

Code: Alles auswählen

letzter@ptLWL01:~/barcode/test$ ./crony_.sh
./crony_.sh: 4: 1: parameter not set
letzter@ptLWL01:~/barcode/test$ 
Und nu :?:
Ah, hätte ich dazuschreiben können. Das Skript erwartet den Quellordner mit den PDFs als Argument beim Aufrufen (deshalb srcdir=$1). Also in diesem Fall einfach:

Code: Alles auswählen

letzter@ptLWL01:~/barcode/test$ ./crony_.sh .
Wenn du es später benutzen willst, kannst du auch, wie in den anderen Skripten, den Ordner fix festlegen, etwa:

Code: Alles auswählen

srcdir=/home/letzter/barcode/test
Und dann wiederum das Argument beim Aufruf weglassen.
Manchmal bekannt als Just (another) Terminal Hacker.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 05.05.2022 20:48:22

JTH hat geschrieben: ↑ zum Beitrag ↑
27.04.2022 17:51:02

watch_pdf_dir:

Code: Alles auswählen

#!/bin/bash
set -u

log()
{
    printf "%(%c)T: %s" -1 "$*"
}

watched_dir=/ueber/den/wolken

inotifywait -e close_write -e moved_to --format '%w%f' -mq "$watched_dir" | while read -r filename; do
	basename=${filename##*/}
	if [[ ! $basename =~ ^[^.].*\.pdf$ ]]; then
		# Ignoriere zumindest versteckte und Nicht-PDF-Dateien
		continue
	fi

	subject=
	if ! output="$(rename_from_barcode "$filename" 2>&1)"; then
		subject="Failed to move '$basename'"
		mail -s "$subject" letzter <<<"$output"
	fi
	log "$subject${subject:+: }$output"
done
Kann es sein, dass hier das rename-script gar nicht aufgerufen wird?
Alles an seinen Platz geschoben, Rechte vergeben, service enabled und gestartet.
Es passiert aber nichts, ausser das ein log mit Zeitstempeln (ansonsten ohne Inhalt) angelegt wird.

Code: Alles auswählen

root@ptLWL01:~# systemctl status watch-pdf-dir.service
● watch-pdf-dir.service - Watch PDF directory
     Loaded: loaded (/etc/systemd/system/watch-pdf-dir.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-05-05 20:23:46 CEST; 16min ago
   Main PID: 790399 (watch_pdf_dir)
      Tasks: 3 (limit: 3525)
     Memory: 9.9M
        CPU: 3.637s
     CGroup: /system.slice/watch-pdf-dir.service
             ├─790399 /bin/bash /usr/local/bin/watch_pdf_dir
             ├─790400 inotifywait -e close_write -e moved_to --format %w%f -mq /home/public/LWL/PDF-Ablage/Rechnungen
             └─790401 /bin/bash /usr/local/bin/watch_pdf_dir

Mai 05 20:23:46 ptLWL01 systemd[1]: Started Watch PDF directory.
root@ptLWL01:~# 

Code: Alles auswählen

root@ptLWL01:~# cat /usr/local/bin/watch_pdf_dir
#!/bin/bash
set -u

log()
{
    printf "%(%c)T: %s" -1 "$*"
}

watched_dir=/home/public/LWL/PDF-Ablage/Rechnungen

inotifywait -e close_write -e moved_to --format '%w%f' -mq "$watched_dir" | while read -r filename; do
        basename=${filename##*/}
        if [[ ! $basename =~ ^[^.].*\.pdf$ ]]; then
                # Ignoriere zumindest versteckte und Nicht-PDF-Dateien
                continue
        fi

        subject=
        if ! output="$(/home/letzter/barcode/rename_from_barcode.sh "$filename" 2>&1)"; then
                subject="Failed to move '$basename'"
                mail -s "$subject" letzter <<<"$output"
        fi
        log "$subject${subject:+: }$output"
done
root@ptLWL01:~# 

Code: Alles auswählen

root@ptLWL01:~# cat /etc/systemd/system/watch-pdf-dir.service
[Unit]
Description=Watch PDF directory
Before=smbd.service

[Service]
ExecStart=/usr/local/bin/watch_pdf_dir
StandardOutput=append:/var/log/watch-pdf-dir.log
StandardError=inherit

[Install]
WantedBy=multi-user.target
root@ptLWL01:~# 

Code: Alles auswählen

root@ptLWL01:~# cat /home/letzter/barcode/rename_from_barcode.sh
#!/bin/bash
set -eu -o pipefail

destname_pdftotext()
{
        pdftotext "$1" - | grep -m1 "^\*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.*\*$" | tr -d '*'
}

destname_zbarimg()
{
        zbarimg -q -Sdisable -Scode39.enable <(pdftoppm -png -singlefile "$1")  | cut -d: -f2-  | tr ' ' _
}

: "${method:=zbarimg}"
srcfile=$1
destdir=/home/public/LWL/PDF-Ablage/Rechnungen_mit_Nummern/
destname=$("destname_$method" "$srcfile").pdf

mv -nv -- "$srcfile" "${destdir%/}/${destname}"
root@ptLWL01:~# 

Code: Alles auswählen

root@ptLWL01:~# cat /var/log/watch-pdf-dir.log
Do 05 Mai 2022 20:24:19 CEST: Do 05 Mai 2022 20:27:37 CEST:
root@ptLWL01:~# 
Insgesamt 3 x ne Datei in den Ordner /home/public/LWL/PDF-Ablage/Rechnungen kopiert. 2 x ein PDF, dass sind die beiden Zeitstempel. 1 x eine txt (eine umbenannte valide PDF), kein Zeitstempel.

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von JTH » 06.05.2022 12:36:25

letzter3 hat geschrieben: ↑ zum Beitrag ↑
05.05.2022 20:48:22
Kann es sein, dass hier das rename-script gar nicht aufgerufen wird?
Hmm, ja, wäre bei den längeren Beiträgen nicht auszuschließen, dass ich beim Zusammenkopieren und Formatieren mal ’nen Fehler einbaue. Ich hab aber beim Überfliegen so jetzt keinen gesehen und deine Schritte klingen soweit richtig.

Existiert evtl. die Zieldatei schon? Das mv wird im rename_from_barcode mit -n (kurz für --no-clobber) aufgerufen. Damit werden existierende Zieldateien nicht überschrieben. mv meldet das allerdings – ganz regulär und erwartet – nicht und gibt keinen Fehler. Das könnte zu den leeren Logzeilen führen. Die Option hatte ich beim Herumbasteln mal benutzt und anscheinend nicht mehr rausgenommen.

Wenn das mögliche Überschreiben schon existierender Dateien kein Problem wär, kannst du die Option ja rausnehmen. Wenn sie drin bleiben soll, könnt man im rename_from_barcode noch eine Meldung ergänzen, wenn eine Datei nicht verschoben wurde, weil das Ziel schon existiert.

Ich denk mal, zum Ausprobieren stört die Option mehr, in der Praxis wäre aber eine Meldung ohne Überschreiben einer existierenden, schon umbenannten Datei sinnvoll?
Manchmal bekannt als Just (another) Terminal Hacker.

letzter3
Beiträge: 447
Registriert: 16.07.2011 22:07:31

Re: PDF an Hand des hinterlegten barcodes umbenennen

Beitrag von letzter3 » 07.05.2022 12:09:39

JTH hat geschrieben: ↑ zum Beitrag ↑
06.05.2022 12:36:25
Existiert evtl. die Zieldatei schon? Das mv wird im rename_from_barcode mit -n (kurz für --no-clobber) aufgerufen. Damit werden existierende Zieldateien nicht überschrieben. mv meldet das allerdings – ganz regulär und erwartet – nicht und gibt keinen Fehler. Das könnte zu den leeren Logzeilen führen. Die Option hatte ich beim Herumbasteln mal benutzt und anscheinend nicht mehr rausgenommen.
Ja, dass schient tatsächlich das Problem gewesen zu sein.
JTH hat geschrieben: ↑ zum Beitrag ↑
06.05.2022 12:36:25
Wenn sie drin bleiben soll, könnt man im rename_from_barcode noch eine Meldung ergänzen, wenn eine Datei nicht verschoben wurde, weil das Ziel schon existiert.

Ich denk mal, zum Ausprobieren stört die Option mehr, in der Praxis wäre aber eine Meldung ohne Überschreiben einer existierenden, schon umbenannten Datei sinnvoll?
Das wäre sinnvoll, ja.

Zur Zeit sieht das log so aus:
root@ptLWL01:~# cat /var/log/watch-pdf-dir.log

Code: Alles auswählen

Do 05 Mai 2022 20:24:19 CEST: Do 05 Mai 2022 20:27:37 CEST: Fr 06 Mai 2022 12:16:19 CEST: Datei umbenannt '/home/public/LWL/PDF-Ablage/Rechnungen/2022-05-06 12-16-16 Unbenannt.pdf' -> '/home/public/LWL/PDF-Ablage/Rechnungen_mit_Nummern/2022-05-06_VR-795.pdf'Sa 07 Mai 2022 11:57:07 CEST: Datei umbenannt '/home/public/LWL/PDF-Ablage/Rechnungen/2022-05-06_VR-795.pdf' -> '/home/public/LWL/PDF-Ablage/Rechnungen_mit_Nummern/2022-05-06_VR-795.pdf'
Schön wäre eine Formatierung wie:

Code: Alles auswählen

2022-05-05 20:24:19 CEST: 
2022-05-05 20:27:37 CEST:
2022-05-06 12:16:19 CEST: Datei umbenannt '/home/public/LWL/PDF-Ablage/Rechnungen/2022-05-06 12-16-16 Unbenannt.pdf' -> '/home/public/LWL/PDF-Ablage/Rechnungen_mit_Nummern/2022-05-06_VR-795.pdf'
2022-05-07 11:57:07 CEST: Datei umbenannt '/home/public/LWL/PDF-Ablage/Rechnungen/2022-05-06_VR-795.pdf' -> '/home/public/LWL/PDF-Ablage/Rechnungen_mit_Nummern/2022-05-06_VR-795.pdf' 
Und ein paar weitere Anforderungen haben sich nun im Echtbetrieb noch ergeben.....
Ich versuche mal, das zu struktieren.

Antworten