ryeballar ryeballar - 4 months ago 12
Bash Question

Shell globbing negation doesn't work in bash

I'm currently confused why shell globbing in terminal works with negation but shows an error when running in bash.

Take the commands executed in the terminal below, which shows all js files within the

directory except for js files that ends with

$ shopt -s globstar
$ ls ./HTML/**/!(*.bundle).js

The command above works perfectly, now let's put it in a bash file


#!/usr/bin/env bash

shopt -s globstar
ls ./HTML/**/!(*.bundle).js

Executing it in a terminal:

$ bash list-js.sh
list-js.sh: line 4: syntax error near unexpected token `('
list-js.sh: line 4: `ls ./HTML/**/!(*.bundle).js'

As you can see, it shows a syntax error.


globstar only enables the ** pattern. The extglob option allows !(...). Somewhere in your interactive shell, that has already been enabled (perhaps in your .bashrc, perhaps you typed shopt -s extglob earlier). However, it needs to be enabled explicitly in your script, since such settings are not inherited from the shell that starts the script.

#!/usr/bin/env bash

shopt -s globstar extglob
ls ./HTML/**/!(*.bundle).js

(As an aside, ** without globstar does not cause a syntax error because it is treated simply as two adjacent *s, the second one being redundant.)