Bash Bash Script Anweisung mit Abhängigkeit

Art Vandelay

Lieutenant
Registriert
Apr. 2020
Beiträge
802
Hallo,

ich fummele mich grade in einem Bash Script auf dem Raspi zurecht, es ist grausam. In der Windows Powershell Welt wäre es so einfach, aber die läuft auf dem Raspi1 noch nicht, also muss es ein Bash Script sein.

Ich habe ein Backup Script, das via rsync ein Verzeichnis von einem anderen System (USB Stick an Fritzbox) synchronisiert. Nun möchte ich, dass nur bei Veränderungen des synchronisierten Verzeichnisses die weiteren Schritte ausgeführt werden (Verzeichnis mit 7z packen und in eine Cloud sichern). Natürlich könnte ich das auch stupide immer durchrennen lassen, aber wäre sehr unnötig, wenn es nur hin und wieder mal Veränderungen im Backup Verzeichnis gibt.

Meine Idee: Ich frage ab ob es geänderte Dateien im Backup Verzeichnis gibt, hierfür gibt es ja den Befehl
Bash:
find /data/verz -type f -mtime -1
Dieser gibt mir aus, ob es im Verzeichnis /data/verz geänderte Dateien in den letzten 24h gibt.
Nur wie kann ich diese Information im Script auswerten?
Die Variable $? gibt immer eine 0 aus, egal was der find Befehl ausspuckt.

Ich hatte auch die Idee die Ausgabe des find Befehls in eine Datei umzuleiten und dann abzufragen ob die Datei existiert. Dummerweise wird die Datei immer erzeugt, auch ohne Inhalt. Also läuft der folgende Code immer in die Then Bedingung rein
Bash:
TMPFILE=/data/tmp.txt
find /data/verz -type f -mtime -1 > $TMPFILE
if [ -f "$TMPFILE" ]; then
<BACKUP ANWEISUNGEN>
fi
rm $TMPFILE

Also wie löse ich diese Banalität?

Mit Powershell würde ich es ganz easy so lösen:
PowerShell:
if (ls -path c:\data\verz | where {$_.LastWriteTime -gt (get-date).AddDays(-2)})
{<BACKUP ANWEISUNGEN}
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: GTrash81 und madmax2010
Abgesehen davon: Du scheinst da gerade ein Backup tool selber zu implementieren.
Hast du schon mechanismen zur Verifikation deiner backups, zur gescheiten verschluesselung und zur Versionsverwaltung implementiert?
Falls nicht gibts sowas schon fertig..
So machst du halt backups, die auch immer mal wider korrupt sein koennen und auf die Fremde Zugriff haben, wenn du die Cloud nicht selber betreibst
TL;DR: Was @Yuuri sagt
 
Zuletzt bearbeitet:
Code:
if [ -n "$(find /foo/bar -type f -mtime -1 -print -quit)" ]
then
    # backup
fi
Abseits davon würde ich eher auf restic setzen.
 
  • Gefällt mir
Reaktionen: sandreas und madmax2010
Über find zu gehen ist ein ziemlicher Umweg. Rsync zeigt doch die synchronisierten Dateien an, also z.B.::
Code:
thomas@localhost:/tmp> rsync -ai test1 test2
cd+++++++++ test1/
>f+++++++++ test1/t
Wird nichts synchronisiert, das Backup also aktuell ist, wird auch nichts angezeigt.
Also ganz einfach die Ausgabe von rsync parsen. Links wie das geht wurden ja bereits von tollertyp gepostet.
 
  • Gefällt mir
Reaktionen: Art Vandelay
tollertyp schrieb:
Die Ausgabe kann man in der Bash viel einfacher in eine Variable packen als den Umweg über eine Datei.
Google ist doch bestimmt dein Freund?

https://www.google.com/search?q=bash+program+output+to+variable
Erster Treffer:
https://linuxhint.com/bash_command_output_variable/

Manchmal muss man halt auch einfach auf die richtigen Suchbegriffe kommen. Genau das habe ich gesucht. Damit wird's sicher klappen :-)

@All:
Ich mag gerne Boardmittel, Restic habe ich hier aufm Windows Laptop auch laufen. Ist irgendwie nicht so mein Ding. Für den privaten Gebrauch darf's halt gerne auch mal easy sein ohne Enterprise Hintergedanken, Versionierung und Verifizierung.
 
Unter Linux gibt es aber by Design keine bordmittel. Und auch PS ist in vorliegender Form erst seit win10 dabei, klar gibts ps mit Windows seit Vista, aber immer in einer eher inkompatiblen Version; die aktuellst mögliche PS für ein Windows mußte man händisch auf eigene Initiative installieren und selbst dann war das teilweise inkompatibel von Windows zu Windows und zwischen Clients und Servern ist es da immer noch.

Bash ist zwar signifikant angenehmer als batch, aber ist definitiv auch nicht mehr das mittel der Wahl. Ebenso wie Perl ist die Zeit einfach rum, wobei es sicherlich länger leben wird als batch.

Gibt genug Interpreter unter unixoiden Systemen. PHP und Python sind nur zwei.

Was ps unter raspi angeht gebe ich zu nicht noch mal geschaut zu haben, möchte aber erwähnen, dass ps überall da läuft wo net5/6/7 laufen. Beide, netcore und ps, sind open source.

Daher, einfach mal probiert das zu kompilieren?
 
+1 für den Vorschlag von @Mystery1988
Beim Parsen einer find-Ausgabe sollte man Vorsicht walten lassen, denn es kann durchaus den (seeeeehr unwahrscheinlichen) Fall geben, dass z.B. ein Dateiname ein Newline-Symbol enthält. Oder wenn man nicht richtig quoted, können auch Leerzeichen in Dateinamen Probleme machen.
 
Iqra schrieb:
Was ps unter raspi angeht gebe ich zu nicht noch mal geschaut zu haben, möchte aber erwähnen, dass ps überall da läuft wo net5/6/7 laufen. Beide, netcore und ps, sind open source.

Daher, einfach mal probiert das zu kompilieren?

Ja, der Raspi 1B sowie der Raspi Zero (1) bringt beim ausführen von pwsh eine Speicher Fehlermeldung. Auf einem Raspi 4 läuft die pwsh ohne Probleme.
1672693332951.png

Ergänzung ()

Mystery1988 schrieb:
Nur eine kurze Frage, warum arbeitest du nicht beim find Befehl mit dem Parameter exec?
https://wiki.ubuntuusers.de/find/
Mit dem Parameter kannst du Aktionen auf die gefundene Datei ausüben.

Hab gesehen, dass das geht, aber passt nicht wirklich in meinen Plan. Dann würde er ja für jede via find gefundene Datei einen Befehl ausführen. Vom parsen des find Befehls habe ich mich jetzt verabschiedet.
Ergänzung ()

Meine Lösung sieht nun so aus und scheint bisher zu laufen:

Bash:
syncvar=$(rsync -ai --delete /quell/verz /ziel/verz/)

if [ -z "$syncvar" ]; then
  echo "Keine Aenderungen!"
else
  <BACKUP ANWEISUNGEN>
fi

Danke an @tollertyp und @umask007 für die guten Denkanstöße :-)
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: tollertyp
Zurück
Oben