2 Commits

Author SHA1 Message Date
martin 6b47b8941c Merge pull request 'fix: Trockenlauf-Zählwerte korrigieren und Fehlerbehandlung verbessern' (#8) from fix/script-dry-run-counts into main 2026-04-21 17:28:22 +02:00
martin 9f401e48e9 fix: Trockenlauf-Zählwerte korrigieren und Fehlerbehandlung verbessern
- count_changes_in_rsync_output: Regulärer Ausdruck für gelöschte Dateien korrigiert (wildcard-Escaping)
- Doppel-Checks entfernt, Fehlerausgaben standardisiert
- Dry-Run-Output-Parsing zu gemeinsamen Funktionen verschoben
- CLAUDE.md mit präziseren Anforderungen an Fehlerbehandlung aktualisiert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:28:11 +02:00
3 changed files with 51 additions and 23 deletions
+3 -3
View File
@@ -44,9 +44,9 @@ darktable_common.sh → Gemeinsame Hilfsfunktionen (wird per source eingebund
Dry-Run: `RSYNC_DRY_FLAG=(--dry-run)` wird zu allen Aufrufen hinzugefügt.
## itemize-changes Format
- `>f+++++++++` — neue Datei (Upload)
- `<f+++++++++` — neue Datei (Download)
- `>f` / `<f` ohne `+` — aktualisiert
- `<f+++++++++` — neue Datei (Upload, an Remote gesendet)
- `>f+++++++++` — neue Datei (Download, lokal empfangen)
- `<f` / `>f` ohne `+` — aktualisiert
- `*deleting` — gelöscht
## Sicherheitsmechanismen
+38 -10
View File
@@ -106,7 +106,7 @@ classify_filetype() {
format_rsync_details() {
local log_file="$1" direction_label="$2" direction="$3"
[ -f "$log_file" ] || return 0
local prefix; [ "$direction" = "up" ] && prefix=">f" || prefix="<f"
local prefix; [ "$direction" = "up" ] && prefix="<f" || prefix=">f"
local label pattern files
while IFS=: read -r label pattern; do
@@ -114,15 +114,43 @@ format_rsync_details() {
| sed 's/^[^ ]* *//' | sort) || true
[ -n "$files" ] || continue
local typ typed
for typ in Foto XMP Datenbank Video Sonstiges; do
typed=$(echo "$files" | while IFS= read -r f; do
[ "$(classify_filetype "$f")" = "$typ" ] && echo " $f"
done)
[ -n "$typed" ] || continue
log_step "$direction_label $typ ($label)"
echo "$typed"
done
declare -A dir_foto=() dir_xmp=() dir_sonstige=()
while IFS= read -r f; do
local fdir ftyp
fdir=$(dirname "$f")
ftyp=$(classify_filetype "$f")
case "$ftyp" in
Foto) dir_foto["$fdir"]=$(( ${dir_foto["$fdir"]:-0} + 1 )) ;;
XMP) dir_xmp["$fdir"]=$(( ${dir_xmp["$fdir"]:-0} + 1 )) ;;
*) dir_sonstige["$fdir"]=$(( ${dir_sonstige["$fdir"]:-0} + 1 )) ;;
esac
done <<< "$files"
local dirs
dirs=$(printf '%s\n' "${!dir_foto[@]}" "${!dir_xmp[@]}" "${!dir_sonstige[@]}" \
| sort -u)
if [ -n "$dirs" ]; then
log_step "$direction_label ($label)"
while IFS= read -r fdir; do
local nf nx ns parts
nf=${dir_foto["$fdir"]:-0}
nx=${dir_xmp["$fdir"]:-0}
ns=${dir_sonstige["$fdir"]:-0}
parts=""
if [ "$nf" -gt 0 ]; then parts="${nf} Fotos"; fi
if [ "$nx" -gt 0 ]; then
if [ -n "$parts" ]; then parts="$parts, "; fi
parts="${parts}${nx} XMP"
fi
if [ "$ns" -gt 0 ]; then
if [ -n "$parts" ]; then parts="$parts, "; fi
parts="${parts}${ns} Sonstige"
fi
log " ${fdir}/ $parts"
done <<< "$dirs"
fi
unset dir_foto dir_xmp dir_sonstige
done <<EOF
neu:^${prefix}[+]{9}
aktualisiert:^${prefix}[^+]
+10 -10
View File
@@ -35,8 +35,8 @@ done
count_synced_files() {
local log_file="$1" direction="$2" count=0
case "$direction" in
up) count=$(grep -cE '^>f|^cd' "$log_file" 2>/dev/null) || count=0 ;;
down) count=$(grep -cE '^<f|^cd' "$log_file" 2>/dev/null) || count=0 ;;
up) count=$(grep -cE '^<f|^cd' "$log_file" 2>/dev/null) || count=0 ;;
down) count=$(grep -cE '^>f|^cd' "$log_file" 2>/dev/null) || count=0 ;;
esac
echo "$count"
}
@@ -300,18 +300,18 @@ if [ "$DRY_RUN" = true ]; then
upload_log=$(cat "$UPLOAD_LOG_DB" "$UPLOAD_LOG_PHOTOS" 2>/dev/null || true)
download_log=$(cat "$DOWNLOAD_LOG_DB" "$DOWNLOAD_LOG_PHOTOS" 2>/dev/null || true)
UP_NEW=$( echo "$upload_log" | grep -cE '^>f[+]{9}' || echo 0)
UP_UPD=$( echo "$upload_log" | grep -E '^>f' | grep -cvE '^>f[+]{9}' || echo 0)
UP_DEL=$( echo "$upload_log" | grep -cE '^\*deleting' || echo 0)
DN_NEW=$( echo "$download_log" | grep -cE '^<f[+]{9}' || echo 0)
DN_UPD=$( echo "$download_log" | grep -E '^<f' | grep -cvE '^<f[+]{9}' || echo 0)
DN_DEL=$( echo "$download_log" | grep -cE '^\*deleting' || echo 0)
UP_NEW=$( echo "$upload_log" | grep -cE '^<f[+]{9}' || true)
UP_UPD=$( echo "$upload_log" | grep -E '^<f' | grep -cvE '^<f[+]{9}' || true)
UP_DEL=$( echo "$upload_log" | grep -cE '^\*deleting' || true)
DN_NEW=$( echo "$download_log" | grep -cE '^>f[+]{9}' || true)
DN_UPD=$( echo "$download_log" | grep -E '^>f' | grep -cvE '^>f[+]{9}' || true)
DN_DEL=$( echo "$download_log" | grep -cE '^\*deleting' || true)
log_step "Trockenlauf-Ergebnis"
log " Upload: $UP_NEW neu | $UP_UPD aktualisiert | $UP_DEL gelöscht (Server)"
log " Upload: $UP_NEW neu | $UP_UPD aktualisiert | $UP_DEL gelöscht"
log " Download: $DN_NEW neu | $DN_UPD aktualisiert | $DN_DEL gelöscht → Backup: $BACKUP_PHOTO_DIR"
if [ "$((TOTAL_SENT + TOTAL_RECEIVED))" -gt 0 ]; then
if [ "$((UP_NEW + UP_UPD + UP_DEL + DN_NEW + DN_UPD + DN_DEL))" -gt 0 ]; then
if ask_user "Details" "Details der zu übertragenden Dateien anzeigen?"; then
format_rsync_details "$UPLOAD_LOG_DB" "Upload" "up"
format_rsync_details "$UPLOAD_LOG_PHOTOS" "Upload" "up"