Escaping ** correctly

Hello

This should be easy, but bash is giving me headaches.

At the command line the following command works:

duplicity --include /home --exclude '**' / file:///foo

Doing that from a script is not straightforward. Note that it is basically a requirement that I place the includes and excludes into variables.

These alternatives do not work, as none of them produces the above output:

args="--include /home --exclude '**'"
duplicity $args src tgt

args='--include /home --exclude **'
duplicity $args src tgt

args="--include /home --exclude \*\*"
duplicity $args src tgt

args="--include /home --exclude **"
duplicity "$args" src tgt

So what is the magic incantation, please?

The problem is that you can't put quoted strings inside variables and expect them to get split sanely AFTER substitution has already happened. It'll split apart on spaces but not much else. It doesn't re-check for quoted strings etc. after substitution's already happened. So your script isn't being given , it's being given '', quotes and all! And yet, if you remove the quotes, it WILL substitute for *, even though it doesn't substitute for strings...

Put them in an array so there's no guessing at all involved in which parts are string, which parts are quotes, and where it should split them apart; it'll do so just like you'd expect of program arguments. There's a magic syntax to spit out an entire array as properly separated parameters too.

ARGS=( --include /home --exclude "**" )
# This array syntax spits out an array, splitting ONLY between elements.
program "${ARGS[@]}"

This won't work in ordinary sh, which doesn't have arrays.

1 Like

Hello,

you can use --exclude-regexp if you dont have any files starting with a dot in the current directory. so the glob would not be expanded

args="--include /home --exclude-regexp '.*'"

One question: why do you need to have --exclude? Is duplicity recursive in nature.?

anyways I hope that solves your problem.

Regards,
Gaurav.

Thanks, that's got it fixed.