ryeballar
ryeballar

Reputation: 30098

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 ./HTML directory except for js files that ends with .bundle.js.

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

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

list-js.sh

#!/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.

Upvotes: 2

Views: 1025

Answers (1)

chepner
chepner

Reputation: 531315

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.)

Upvotes: 8

Related Questions