Reputation: 596
Example bash script demonstrating my problem:
#!/bin/bash
function exclude
{
BACKUP_EXCLUDES="$BACKUP_EXCLUDES --exclude=\"$1\""
}
exclude "/proc"
exclude "/dev"
exclude "/mnt"
exclude "/media"
exclude "/lost+found"
echo $BACKUP_EXCLUDES
Output:
--exclude="/proc" --exclude="/dev" --exclude="/mnt" --exclude="/media" --exclude="/lost+found"
Perfect! But when I try adding:
rsync -ruvz $BACKUP_EXCLUDES / /some/backup/path
$BACKUP_EXCLUDES is completely ignored with no errors or warnings... Why?
Upvotes: 1
Views: 683
Reputation: 53158
you need to use array:
#!/usr/bin/env bash
BACKUP_EXCLUDES=()
function exclude
{
while
(( $# ))
do
BACKUP_EXCLUDES+=(--exclude="$1")
shift
done
}
exclude /proc /dev /mnt /media
exclude "/lost+found"
rsync -ruvz "${BACKUP_EXCLUDES[@]}" / /some/backup/path
the bash explanation: please check @janos answer
the zsh explanation (if it was Zsh): when you used a string variable it was like you passed --exclude="\"/proc\" --exclude=\"/media\" ..."
- so it was treated as long path with spaces - which never matched.
Upvotes: 3
Reputation: 124646
It doesn't work because the quotes are included in the individual --exclude
parameters. That is, rsync
will ignore "/proc"
instead of /proc
. Of course "/proc"
(with quotes) doesn't exist.
If you stick an eval in front of the command it will work, like this:
eval rsync -ruvz $BACKUP_EXCLUDES / /some/backup/path
In this case the --exclude="/proc"
(and all others) will be evaluated to --exclude=/proc
, that's why it will work.
But I think you should use arrays as proposed by @mpapis, or --exclude-from=FILE
as proposed by a comment. Both are much better and cleaner solutions.
Upvotes: 3