Syntax error near unexpected token `('
Solution 1
rm !(*.sh)
is a extglob
syntax which means remove all files except the ones that have the .sh
extension.
In your interactive bash
instance, the shell option extglob
is on :
$ shopt extglob
extglob on
Now as your script is running in a subshell, you need to enable extglob
by adding this at the start of the script :
shopt -s extglob
So your script looks like :
#!/bin/bash
shopt -s extglob
rm -rf -- !(*.sh)
EDIT :
To remove all files except .sh
extension ones use GLOBIGNORE
(as you don't want to enable extglob
) :
#!/bin/bash
GLOBIGNORE='*.sh'
rm -rf *
Example :
$ ls -1
barbar
bar.sh
egg
foo.sh
spam
$ GLOBIGNORE='*.sh'
$ rm *
$ ls -1
bar.sh
foo.sh
Solution 2
Ok, it's a cross-post, but I have to write an answer. ;)
You could use find
instead
find . -maxdepth 1 ! -name '*.sh' -exec rm -rf {} \;
Solution 3
You need to turn extglob
on:
shopt -s extglob
Related videos on Youtube
Tal
Updated on September 18, 2022Comments
-
Tal over 1 year
When I use below code in Ubuntu terminal, it works fine:
rm !(*.sh) -rf
But if I place the same line code in a shell script (clean.sh) and run the shell script from terminal, it throws an error:
clean.sh script:
#!/bin/bash rm !(*.sh) -rf
The error I get:
./clean.sh: line 2: syntax error near unexpected token `(' ./clean.sh: line 2: `rm !(*.sh) -rf'
can you help?
-
choroba almost 9 years
-
-
choroba almost 9 years@Pilot6: See
man bash
. It enables extended globbing like!(...)
. -
Tal almost 9 yearscan i change my command that do the same without run this?
shopt -s extglob
-
Tal almost 9 yearscan i change my command that do the same without run this?
shopt -s extglob
? -
heemayl almost 9 years@Tal check my edits..
-
Tal almost 9 yearsthanks :) (stack overflaw make me write 15 character in comment :( :( :( )
-
Tal almost 9 yearsbut here there a two good answers!
-
heemayl almost 9 years@Tal No problem..you can select any one.. Me or A.B. won't mind at all..
-
Guntram Blohm almost 9 yearsThis should be the accepted answer, since it actually answers the question, while the other one just describes a workaround.
-
Paddy Landau over 8 yearsIf you want GLOBIGNORE for only the
rm
command and nothing else, enclose in parentheses and use a semicolon thus:( GLOBIGNORE='*.sh'; rm * )
-
Gaël J over 2 yearsHighlighting the fact at it has to be at the start of the script, I had it in the middle and it was not working