I updated that wiki page Hopefully its clearer now. http://mywiki.wooledge.org/glob#extglob
On 02/26/2012 12:06 PM, Dan Douglas wrote: > On Saturday, February 25, 2012 09:42:29 PM Davide Baldini wrote: > >> Description: A 'test.sh` script file composed exclusively of the >> following text fails execution: #!/bin/bash ( shopt -s extglob >> echo !(x) ) giving the output: $ ./test.sh ./test.sh: line 4: >> syntax error near unexpected token `(' ./test.sh: line 4: ` >> echo !(x)' Moving the shopt line above the sub-shell parenthesis >> makes the script work. >> >> The debian man pages give no explanation. >> >> Thank you. > > Non-eval workaround if you're desperate: > > #!/usr/bin/env bash ( shopt -s extglob declare -a a='( !(x) )' echo > "${a[@]}" ) > > You may be aware extglob is special and affects parsing in other > ways. Quoting Greg's wiki (http://mywiki.wooledge.org/glob): > >> Likewise, you cannot put shopt -s extglob inside a function that >> uses extended globs, because the function as a whole must be >> parsed when it's defined; the shopt command won't take effect >> until the function is called, at which point it's too late. > > This appears to be a similar situation. Since parentheses are > "metacharacters" they act strongly as word boundaries without a > special exception for extglobs. > > I just tested a bunch of permutations. I was a bit surprised to see > this one fail: > > f() if [[ $FUNCNAME != ${FUNCNAME[1]} ]]; then trap 'shopt -u > extglob' RETURN shopt -s extglob f else f()( shopt -s extglob echo > !(x) ) f fi > > f > > I was thinking there might be a general solution via the RETURN > trap where you could just set "trace" on functions where you want > it, but looks like even "redefinitions" break recursively, so > you're stuck. Fortunately, there aren't a lot of good reasons to > have extglob disabled to begin with (if any).