Rsync ignoriert doppelte Anführungszeichen im Skript

Rsync ignoriert doppelte Anführungszeichen im Skript

Wenn die Variable "$exclude_list"als Parameter aufgerufen wird, ignoriert rsync Anführungszeichen und schließt irgendwie den Home-Ordner ein, auch wenn dieser im Skript nicht erwähnt wird. Ich habe versucht, es in einzuschließen "${exclude_list}", aber das hat auch nicht geholfen.

Das Anzeigen des Inhalts der Variablen vor der Verwendung in Kombination mit rsynczeigt, dass dieser korrekt ist.

Eine weitere merkwürdige Sache ist, dass echo rsync ...die Ausgabe korrekt ist und keine Fehler auftreten, wenn ich das mache.

Teil des problematischen Bash-Skripts:

    echo "$exclude_list"
    rsync -av --dry-run "$exclude_list" "$src" "$dest" >> /var/log/rsync.log || {
      sendmail "Error: rsync failed for folder $src."; exit 1; }

Ausgabe:

   --exclude=lost+found
   rsync: [sender] link_stat "/home/user/ --exclude=lost+found" failed: No such file or 
   directory (2)
   rsync error: some files/attrs were not transferred (see previous errors) (code 23) at 
   main.c(1333) [sender=3.2.3]

Hier ist der MCVE:

#!/bin/bash

# List of source folders
SRC_FOLDERS=(
  [0]="/mnt/load-1/"
  [1]="/mnt/load-2/"
)

# List of backup folders
DEST_FOLDERS=(
  [0]="/mnt/load-1-b/"
  [1]="/mnt/load-2-b/"
)

# List of folders to exclude during backup
EXCLUDE_FOLDERS=(
  "lost+found"
  "lost-found"
)

  # Form the exclude list for rsync
  for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
    exclude_list="$exclude_list --exclude=$exclude_folder"
  done

# Loop through each folder pair
for i in "${!SRC_FOLDERS[@]}"; do
  src=${SRC_FOLDERS[$i]}
  dest=${DEST_FOLDERS[$i]}

    rsync -av --dry-run "$exclude_list" "$src" "$dest"

done

Antwort1

Das Problem liegt in

for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
  exclude_list="$exclude_list --exclude=$exclude_folder"
done

Sie iterieren über ein Array EXCLUDE_FOLDERSund erstellen exclude_listdaraus eine Nicht-Array-Variable. Wenn später darauf verwiesen wird "$exclude_list", wird es von der Shell zu einem einzelnen Wort erweitert.

Bevor die forSchleife exclude_listleer ist. Die erste Zuweisung innerhalb der Schleife lässt die Variable mit beginnen --exclude…. Beachten Sie das führende Leerzeichen. Aufgrund dieses Leerzeichens rsyncerkennt es dieses Wort nicht als Option, sondern alsrelativer Pfad. Ich glaube, Ihr aktuelles Arbeitsverzeichnis ist /home/user/. Der absolute Pfad ist daher /home/user/ --exclude=…, eine solche Datei existiert nicht, das ist die Fehlermeldung.

Selbst wenn das führende Leerzeichen nicht vorhanden wäre und exclude_listirgendwie als erstellt worden wäre --exclude=… --exclude=…, wäre es trotzdem falsch. "$exclude_list"wird immer zu einem einzelnen Wort erweitert. Sie möchten, --exclude=…dass jedes ein separates Argument für ist rsync.

Das Nichtzitieren $exclude_listkönnte irgendwie funktionieren, ist aber eine schlechte Lösung; zBes wird (oder kann) fehlschlagen, wenn Elemente EXCLUDE_FOLDERSLeerzeichen, Tabulatoren oder Zeilenumbrüche enthalten (oder Platzhalter, die Globbing auslösen).

Bitte lesen SieWie können wir einen in einer Variablen gespeicherten Befehl ausführen?In Bash ist es oft am besten, ein Array zu verwenden. Erstellen Sie exclude_listein Array:

for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
  exclude_list+=("--exclude=$exclude_folder")
done

Dann im Aufruf von rsyncuse "${exclude_list[@]}".

verwandte Informationen