I'm trying to create a script which I can set as a cron job which adds all my dotfiles to a folder I've set up as a github repo then push them every evening. My script is the following.

cp ~/.!(|.|ssh|bash_logout|bash_history) ~/dotfiles

git add .

git commit -m "Test commit"

git push origin master

I'm getting the following error:

./update_dotfiles.sh: line 3: syntax error near unexpected token `('
./update_dotfiles.sh: line 3: `cp ~/.!(|.|ssh|bash_logout|bash_history) ~/dotfiles'

The command works perfectly when I run it it just errors when i'm running is as part of a shell script.The script is running bash,

  • Which shell are you executing it with when running manually and when invoking from a script?
    – s3lph
    Jan 20, 2016 at 22:05
  • It's running in bash, sorry I should have mentioned that.
    – Ben Moore
    Jan 20, 2016 at 22:06
  • Please manually expand the ~, it may not work in all scripts
    – s3lph
    Jan 20, 2016 at 22:07
  • 2
    Put shopt extglob on the line before the cp command and post what it prints out.
    – jw013
    Jan 20, 2016 at 22:09
  • 1
    In an interactive bash shell, the extglob option is enabled by default (I think), but for a non-interactive script, you have to explicitly turn it on. Jan 20, 2016 at 22:20

1 Answer 1


You need to specify the bash shell in the shebang for this to work:


When bash runs a script without a shebang or with #!/bin/sh it runs in POSIX mode which has some limitations.

You also need to enable the extglob shell option in bash to make it understand the !(...) globbing pattern:

shopt -s extglob

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .