![Rsync ignora las comillas dobles en el script](https://rvso.com/image/1684445/Rsync%20ignora%20las%20comillas%20dobles%20en%20el%20script.png)
Cuando "$exclude_list"
se llama a la variable como parámetro, rsync ignora las comillas dobles y de alguna manera incluye la carpeta de inicio incluso si no se menciona en el script. Intento resumirlo en "${exclude_list}"
, pero eso tampoco ayudó.
Mostrar el contenido de la variable antes de usarla en combinación con rsync
, muestra que es correcto.
Otra cosa extraña es que cuando lo hago echo rsync ...
el resultado es correcto y no hay errores.
Parte del script bash problemático:
echo "$exclude_list"
rsync -av --dry-run "$exclude_list" "$src" "$dest" >> /var/log/rsync.log || {
sendmail "Error: rsync failed for folder $src."; exit 1; }
Producción:
--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]
Aquí está el 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
Respuesta1
El problema está en
for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do exclude_list="$exclude_list --exclude=$exclude_folder" done
Se itera sobre una matriz EXCLUDE_FOLDERS
y se crea una variable que no es de matriz exclude_list
a partir de ella. Cuando luego se hace referencia a él como "$exclude_list"
, el shell lo expande a una sola palabra.
Antes de que el for
bucle exclude_list
esté vacío. La primera asignación dentro del bucle hace que la variable comience con --exclude…
. Tenga en cuenta el espacio inicial. Debido a este espacio rsync
no se reconoce esta palabra como una opción; lo reconoce como uncamino relativo. Creo que su directorio de trabajo actual es /home/user/
. Por lo tanto, la ruta absoluta es /home/user/ --exclude=…
, dicho archivo no existe, esto es lo que indica el error.
Incluso si el espacio principal no estuviera allí y exclude_list
se creara de alguna manera como --exclude=… --exclude=…
, seguiría siendo incorrecto. "$exclude_list"
siempre se expande a una sola palabra. Desea que cada uno --exclude=…
sea un argumento independiente rsync
.
No citar $exclude_list
puede funcionar, aunque es una mala solución; p.ejfallará (o puede) fallar si los elementos EXCLUDE_FOLDERS
contienen espacios, tabulaciones o nuevas líneas (o comodines que activan el globbing).
Por favor lee¿Cómo podemos ejecutar un comando almacenado en una variable?En Bash suele ser mejor utilizar una matriz. Haz exclude_list
una matriz:
for exclude_folder in "${EXCLUDE_FOLDERS[@]}"; do
exclude_list+=("--exclude=$exclude_folder")
done
Luego en la invocación de rsync
uso "${exclude_list[@]}"
.