Você precisa
shopt -s extglob
dentro do script.
Sua configuração bash presumivelmente liga automaticamente para shells interativos (talvez porque você carregue o pacote bash-completion para conclusão sensível ao contexto); você precisa ativá-lo manualmente dentro dos scripts.
Verifique também se o seu script começa com #!/bin/bash
(ou uma variante como #!/usr/bin/env bash
, caso contrário, ele pode ser executado por um shell diferente que não suporta esta sintaxe.
Por exemplo, esse script criará alguns arquivos e, em seguida, removerá todos, exceto os dois que você deseja manter:
$ cat x
#!/bin/bash
shopt -s extglob
touch f1 f2 f3 exec.js .git foo bar
echo Before: $(ls -A)
rm !(exec.js|.git)
echo After: $(ls -A)
Em execução:
$ bash x
Before: .git bar exec.js f1 f2 f3 foo x
rm: cannot remove '.': Is a directory
rm: cannot remove '..': Is a directory
After: .git exec.js
Observe que você recebe erros com .
e ..
; você também viu na linha de comando:
$ touch f1 f2 f3 exec.js .git foo bar
$ rm !(exec.js|.git)
rm: cannot remove '.': Is a directory
rm: cannot remove '..': Is a directory