Question

When running the following command:

rm -rf !(file1|file2)

all files except file1 and file2 are removed; as intended. When either placing this command in a bash script:

#!/bin/bash
rm -rf !(file1|file2)

or running it using bash -c:

bash -c "rm -rf !(file1|file2)"

I receive the following error:

syntax error ner unexpected token '('

I have tried setting the shell options using

shopt -s extglob

yeilding in:

bash -c "shopt -s extglob; rm -rf !(file1|file2)"

to enable glob according to: https://superuser.com/questions/231718/remove-all-files-except-for-a-few-from-a-folder-in-unix and some other questions as well.

Still it doesn't work, and I'm at loss.

Was it helpful?

Solution

First of all, for safety, let's do our testing with echo !(file1|file2) instead of rm -rf !(file1|file2).

Anyway, bash does some parsing of the entire command line before executing the shopt -s extglob command. When bash encounters the (, the extglob option isn't set yet. That's why you get the error.

Try this instead:

bash -O extglob -c 'echo !(file1|file2)'

In your script, you just need to turn on the option as a separate command line before relying on it:

#!/bin/bash
shopt -s extglob
echo !(file1|file2)

You can actually do this with the -c flag also:

bash -c 'shopt -s extglob
echo !(file1|file2)'

Or even like this:

bash -c $'shopt -s extglob\necho !(file1|file2)'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top