1

I'm trying to backup my entire system directory using the following script:

#!/bin/bash

cd /

BACKUP_LOCATION=/media/data/backup/system-backup/

echo Backing up system data to $BACKUP_LOCATION, excluding home directories
sudo rsync -aAXv --exclude={"/home/*", "/swap.img", "/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} / $BACKUP_LOCATION

When running this, I'm getting the following error:

sending incremental file list
rsync: [sender] link_stat "/swap.img," failed: No such file or directory (2)
rsync: [sender] change_dir "/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*," failed: No such file or directory (2)

As far as I understand, the exclude paths are relative to the source directory, being /, therefore e.g. /home/* should resolve to /home/* on the real file system. Can anybody tell me what I am doing wrong here?

2

1 Answer 1

4

When executing the command

sudo rsync -aAXv --exclude={"/home/*", "/swap.img", "/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} / $BACKUP_LOCATION

shells which support brace expansion will only perform it on a word if it contains a correctly-formed brace expression. You can test how the command is interpreted by executing, for example:

 bash -xc 'rsync -aAXvn --exclude={"/home", "/swap.img", "/dev"} / /media/data/backup/system-backup/' 2>&1 | grep ^\+

the result is

+ rsync -aAXvn '--exclude={/home,' /swap.img, '/dev}' / /media/data/backup/system-backup/

in other words, the shell performs word splitting, which converts --exclude={"/home", "/swap.img", "/dev"} into three arguments: --exclude={/home, (which isn't a correctly-formed brace expression, as it doesn't have a closing brace), /swap.img, (including the comma), and /dev}.

If instead the command

bash -xc 'rsync -aAXvn --exclude={"/home","/swap.img","/dev"} / /media/data/backup/system-backup/' 2>&1 | grep ^\+

is executed, we see the correct brace expansion into three separate --exclude arguments:

+ rsync -aAXvn --exclude=/home --exclude=/swap.img --exclude=/dev / /media/data/backup/system-backup/
6
  • 1
    In summary, do not put spaces between components of a brace expansion Apr 14, 2022 at 8:26
  • Unless spaces are desired, in which case they should be protected. Apr 14, 2022 at 8:28
  • They wouldn't be spaces between components then, though. Apr 14, 2022 at 8:29
  • Perhaps it's an issue of semantics, as English is not my native language, but to have spaces at all as part of the brace expression they need to be protected. Apr 14, 2022 at 8:32
  • 1
    {"two words",three\ words\ here} is a valid expansion, but {"two words", alone} is not. I think we mean the same thing - the first one contains spaces that need to be protected within each component but the second one has a space after the comma that breaks the {a,b,c} expansion syntax Apr 14, 2022 at 8:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .