Ich erstelle ein Skript zum Kopieren / Überprüfen von Dateien ... unter Mac OS X / FreeBSD mit der Möglichkeit, eine Portierung nach CentOS, Debian oder OpenBSD vorzunehmen
Mehr zum Drehbuch:
- Überprüfen Sie, ob der Quellpfad Dateien / Unterverzeichnisse enthält
- Erstellen Sie eine oder mehrere Prüfsummen für jedes Verzeichnis / Unterverzeichnis
- tar / komprimiere in den Zielpfad
- Überprüfen Sie die Dateiintegrität im Zielpfad
Natürlich ist es paranoid, weil die Dateiintegritätsprüfungen auf HW / HDD-Ebene durchgeführt werden und von SMART problemlos überprüft werden können, aber zehn Jahre später kann ich die Integrität des Originals nicht überprüfen. Die Prüfsumme wird auf einer CF / XD-Karte erstellt und ist original ... Sie können so viel kopieren, wie Sie möchten, und machen sich keine Gedanken über so genannte faule Bits, HW-Fehler usw.
Natürlich kann auch rsync verwendet werden, aber mir gefällt die Idee, obsolete MD5 / SHA1-Prüfsummen mit möglichen Kollisionen zu verwenden, nicht. Es braucht Stunden Arbeit, "Glück" und Schweiß, um zur richtigen Zeit am richtigen Ort zu sein und ein einzigartiges Foto zu machen ... wenn Sie das Original RAW verlieren ... ist es für immer verschwunden, nur die Erinnerung bleibt.
"Nur Paranoide überleben" - Andy Groove
Ich habe ein einfaches Arbeitsskript für Schritt 1. im Skript:
today=`date +%Y-%m-%d`
CHK='shasum -a512'
CHK_OUTPUT=($today)-checksum.txt
find . -type f ! -name ".*" -maxdepth 1 -exec $CHK {} \; > "$CHK_OUTPUT"
Ich erhalte die erwartete Prüfsummen-Datei, aber die Frage lautet: "Können wir sie verbessern?"
...cf83e1357eef47417a81a538327af927da3e ./(2017-07-19)-checksum.txt
Ich will nervig loswerden ./ also habe ich folgendes codiert ...
find ./ -type f ! -name ".*" -maxdepth 1 -exec bash -c '$CHK $(basename {}) > $CHK_OUTPUT' \;
leider bekomme ich folgenden fehler
bash: ${CHK_OUTPUT}: ambiguous redirect
ein weiterer Versuch
find ./ -type f ! -name ".*" -maxdepth 1 -exec bash -c '$CHK $(basename {})' \; > $CHK_OUTPUT
es funktioniert irgendwie aber mit seltsamen ergebnissen
Ich habe mit UTFM & RTFM versagt und ich habe keine Ahnung, wie ich überhaupt Google fragen soll :-D
Kann jemand vorschlagen, wie es geht, bitte?
Grüße
David
bash
standardmäßig installiert sind.Antworten:
So übergeben Sie Argumente an eine Subshell in
-exec
Mit
find
‚s-exec
können Sie komplexe Befehle übergeben Sie einen Sub - Shell verwenden, wie Sie richtig identifiziert. Es gibt jedoch einige Probleme mit Ihrem Ansatz.Ihre externe Variable
$CHK
wird nicht erweitert, da sie in einfachen Anführungszeichen steht. Was Sie tun können, um der Subshell mitzuteilen, dass diese Variable bereits vorhanden istexport
:Durch das Exportieren einer Variablen wird diese Teil Ihrer Umgebung, die von Subshells gelesen werden kann. Oder Sie übergeben es als separates Argument an die Subshell, die hier die Anlaufstelle ist:
Natürlich können Sie weiter mit
$1
,$2
etc, und verwenden Sie{}
für Ihre Subshell als Argument auch den tatsächlichen Dateinamen zu verwenden. Und vergessen Sie nicht, Ihre Variablen anzugeben.Ihr spezieller Fall
Sie können Ihren Befehl einfach umschreiben in:
weil
shasum
es klug genug ist, die Arbeit in einem Befehl zu erledigen, mehrere Dateien zu lesen, ohne eine Schleife oderfind
. Enthält standardmäßig*
keine Dateien, die mit einem Punkt beginnen (Sie können ihn jedoch mit ändernshopt -s dotglob
), sodass Ihrefind
Optionen nicht erforderlich sind, insbesondere wenn dermaxdepth
Wert 1 ist.Aber tun wir mal so,
shasum
als wäre es nicht so schlau, also kann ich Ihnen noch ein paar Optionen geben. Wenn Sie verwenden möchten, gehenfind
Sie folgendermaßen mit mehreren Argumenten um:Aber auch dann kann dies alles besser lesbar umgeschrieben werden:
Das Durchlaufen von Dateien ist oft einfacher als das Verwenden
find
, obwohl es aufgrund der Erweiterung von eine Beschränkung gibt, wie viele Dateien Sie auf diese Weise verarbeiten können*
- irgendwann wird es für Ihre Befehlszeile zu lang sein (die spezifische Beschränkung hängt von Ihrer ab) Betriebssystem und Shell).Und Sie könnten es natürlich rekursiv mit
shopt -s globstar
Bash ≥ 4.0 machen:Aber das ist wieder dasselbe wie:
quelle
find ./ -type f ! -name ".*" -maxdepth 1 -exec sh -c '$0 "$(basename "$1")"' "$CHK" {} > "$CHK_OUTPUT" \;
$CHK_OUTPUT
vorher oder nachher gibt\;
. Wenn Sie dies zuvor getan haben,find
wird jedes Mal, wenn eine Datei gefunden wird, zu dieser Datei umgeleitet. Sie sollten dies nach demfind
Befehl tun , um die gesamte Ausgabe zu erfassen.AKTUALISIEREN
Leider erzeugt der unten erwähnte Befehl immer noch eine leere Prüfsumme.txt in Unterverzeichnissen, in denen sich keine Datei (en) befinden.
Ich weiß nicht warum, aber es gibt Kludge
=============================================== ===
endgültige Lösung ... scheint soweit zu funktionieren **
quelle