0

As part of a build pipeline I have a shell script that zips up a directory. I want to use a variable to define which patterns should be ignored.

I'm doing something like this:

IGNORE='"*.md" "some-folder/*"'
zip -x $IGNORE -r my-zip.zip ./*

Which doesn't appear to work, the ignored files and folders are still included in the zip archive.

This does work if I create the command and then pipe it through to sh though, so I'm confident that the variable contains the correct values:

echo "zip -x $IGNORE -r my-zip.zip ./*" | sh

I think it might be something to do with the quotes, since this works as expected without them. However this fails as soon as I attempt to add more than 1 pattern to IGNORE.

IGNORE=*.md
zip -x $IGNORE -r my-zip.zip ./*

What am I missing in order to be able to pass these patterns correctly quoted?

Edit: this does also not appear to work as an array, as suggested by this question.

IGNORE='"*.md" "some-folder/*"'
EXCLUDE=($IGNORE)
zip -x ${EXCLUDE[@]} -r my-zip.zip ./*
Tom Davies
  • 899
  • 6
  • 20
  • I don't think so, the top voted answer there assumes I can create an array by passing in multiple variables like `args=( "$f1" "$f2" )`. I don't think it's possible to do something similar here? I could maybe do something to turn `$IGNORE` into an array first? I think this question is different from the one linked though. – Tom Davies May 11 '22 at 10:57
  • 1
    you need an array here: `exclude=("*.md" "./some-folder/*"); zip -x "${exclude[@]}" -r myzip.zip ./*` – Fravadona May 11 '22 at 11:07
  • 1
    See [Correct Bash and shell script variable capitalization](https://stackoverflow.com/q/673055/4154375) for an explanation of why it's unsafe to use ALL_UPPERCASE variable names like `IGNORE`. – pjh May 11 '22 at 11:12
  • @Fravadona - doesn't appear to work when turned into an array either, edited to add failing example with an array. – Tom Davies May 11 '22 at 11:13
  • @pjh - thanks for the heads-up, good to know! – Tom Davies May 11 '22 at 11:14
  • @TomDavies Is the excluding of `"some-folder/*"` that doesn't work? – Fravadona May 11 '22 at 11:17
  • @Fravadona - nope I see both "README.md" and "some-folder/.." being added to the ZIP. The array converting definitely works though, I can access \*.md and some-folder/* using array indices if I just echo them out. – Tom Davies May 11 '22 at 11:17
  • There are several problems with the code in the edit. [Shellcheck](https://www.shellcheck.net/) finds some of them. The code provided by @Fravadona in a comment is good. – pjh May 11 '22 at 11:22
  • Can't answer since this has now been closed, but it turns out that the reason this doesn't work is because of the globbing. The "some-folder/*" gets expanded, rather than passed as a pattern to `zip`. Turning this off with `set -f` before turning `$include` into an array resolves this. – Tom Davies May 11 '22 at 12:46
  • Using a single string to initialize the array doesn't work in general. Using `set -f` may work here, but it isn't sufficient in general. The reliable way to do it is to initialize the array with the literal arguments. All you need to do is to copy and paste the correct code that Fravadona provided. – pjh May 11 '22 at 12:56
  • I can't initialise with the literal arguments, they're sourced from a GitLab variable. I need to turn that value into an array. If I could do that, yes, it would be done already. This is why I asked a new question. – Tom Davies May 11 '22 at 13:49
  • 1
    The answer of @Fravadona is not correct. This solution does not produce the result that is implied when using the `some-folder/*` pattern with zip command. However, the array option will work. The important point is to prevent pattern expansion. Considering @Tom's last question, the solution would be: `read -a exclude_array<<<$IGNORE; zip -x "${exclude_array[@]}" -r my-zip.zip ./*` – seeker May 11 '22 at 22:36
  • @seeker `<<<$IGNORE` is not a good idea, that will convert single/multiple spaces/tabs/newlines to single space. – Fravadona May 13 '22 at 11:57
  • @Fravadona, you're right about space squeezing. But this is not a problem, neither for the filename patterns, nor for the command line arguments. – seeker May 13 '22 at 13:05

0 Answers0