El patrón global de archivos,! (*ejemplo), se comporta de manera diferente en el script bash que en el shell bash

El patrón global de archivos,! (*ejemplo), se comporta de manera diferente en el script bash que en el shell bash

Lo siguiente funciona cuando se pega directamente en mi terminal bash (llamo a bash explícitamente, versión bash 4.4.19(1)-release (x86_64-pc-linux-gnu):)

for filename in /home/dean/Downloads/!(*example).txt; do
    echo "${filename}"
done

Este comando repite todos los archivos de texto que no tienen "ejemplo" en el nombre del archivo.

Pero cuando convierto esto en un script llamado temp.shy chmod +x temp.shlo llamo así ./temp.sh:

#!/usr/bin/env bash

for filename in /home/dean/Downloads/!(*example).txt; do
    echo "${filename}"
done

Obtuve el siguiente error:

dean@dean-thinkpad-p52s:~/Downloads$ ./temp.sh 
./temp.sh: line 3: syntax error near unexpected token `('
./temp.sh: line 3: `for filename in /home/dean/Downloads/!(*example).txt; do'

No entiendo el problema aquí. ¿Por qué hace exactamente lo que quiero en el shell pero no en el script?

Editar (para responderpankila pregunta):

La diferencia entre cuándo envse llama en Shell/terminal y cuándo envse llama en Shell/script:

dean@dean-thinkpad-p52s:~/Downloads$ diff example_myshell.txt example_called_script.txt 
5a6
> _=/usr/bin/env
36,37d36
< TERM=xterm-256color
< SHELL=/bin/bash
38a38,39
> SHELL=/bin/bash
> TERM=xterm-256color
45c46
< PYENV_SHELL=bash
---
> SHLVL=4
47c48
< SHLVL=3
---
> PYENV_SHELL=bash
61d61
< _=/usr/bin/env

Respuesta1

El !(...)operador extendido del shell Korn solo está disponible bashcuando activa la extglobopción (está desactivada de forma predeterminada).

Es posible que haya extglobactivado en su shell interactivo a través de ~/.bashrcu otro archivo de inicialización, pero tenga en cuenta que esos archivos no se obtienen cuando se ejecutan scripts y que esa opción no se hereda del shell que llama (a menos que la BASHOPTSvariable en el entorno, pero sería una mala idea tenerlo ahí).

Encendiéndolo explícitamente con

shopt -s extglob

al principio de su script debería funcionar.

Observe que el shopt -s extglobúnico efecto comienza con la siguiente línea que aún no se ha analizado. Esto significa que no puedes usar shopt -s extgloblike set -fpara activar solo los patrones extendidos en una subcapa:

# this won't work
(
  shopt -s extglob
  echo !(no such file)
)

Tendrías que hacer algo como:

(
  shopt -s extglob
  eval 'echo !(no such file)'
)

información relacionada