I can run this command from my command line prompt:
cp -r folder/!(exclude-me) ./
To recursively copy all contents of folder except for the subdirectory named exclude-me into the current directory. This works exactly as intended. However, I need this to work in a bash script I’ve written, where I have this:
if [ -d "folder" ]; then cp -r folder/!(exclude-me) ./ rm -rf folder fi
But when I run the script:
bash my-script.sh
I get this:
my-script.sh: line 30: syntax error near unexpected token `('
my-script.sh: line 30: ` cp -r folder/!(exclude-me) ./'
And I’m at a loss as to why it works from the command prompt, but the exact same line doesn’t work in a bash script.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
That’s because the syntax you’re using depends on a particular bash feature which is not activated by default for non-interactive shells (scripts). You can activate it by adding the relevant command to your script:
## Enable extended globbing features shopt -s extglob if [ -d "folder" ]; then cp -r folder/!(exclude-me) ./ rm -rf folder fi
This is the relevant section of man bash:
If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the fol‐
lowing sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
Method 2
Add this line near top of your script:
shopt -s extglob
!(...) is an extended pattern matching feature, you need extglob option enable to use it. See shopt builtin for more details.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0