Short Version:
When extended glob is turned on inside a bash if
block on my Mac, the entire block fails with a syntax error on any extend glob pattern contained in the block, even if it follows the activation. It's not a problem on my other machines. Why?
Long Version:
I put the following if
condition around the entirety of my .bashrc
file. Similar if
statements have been put around my other .*
files that are run during a shell's initialisation. I'm doing this to prevent recursive executions on the file if I make an error in the future.
if [ -n "${_BASHRC_INIT}" ] ; then
export _BASHRC_INIT="True"
...
...
...
unset _BASHRC_INIT
fi
I have this function, laa
, defined in my .bashrc
that depends on extended glob. I enable it immediately before I define the function. The function shows all the files in a directory that match .*
excluding .
and ..
. Since I have ls
aliased to ls --color=auto
, it also shows file-type colours, which wouldn't be maintained if I just piped to grep
. It works when not inside an if
block.
shopt -s extglob
laa() {
if [[ $# -eq 1 ]]; then
exec 3>&1 # Another file descriptor for this STDOUT
_items=$(cd "${1}"; ls -d .!(|.)?* 1>&3) # This requires extended glob
# `shopt -s extglob` to enable
exec 3>&- # Close file descriptor
elif [ $# -gt 1 ]; then
exec 3>&1
for i in $@; do
_items=$(cd $i; echo "$i:" 1>&3; ls -d .!(|.)* 1>&3)
done
exec 3>&-
else
ls -d .!(|.)*
fi
}
All the commands contained in the if
block fail to execute on my M1 Mac when the block also contains this excerpt. This problem does not occur with WSL2 (Debian) on my Windows PC. The Mac is running bash 5.2.15
installed with Homebrew and WSL runs bash 5.1.4
.
Specifically, it fails on the ls
commands with the following error.
bash: syntax error near unexpected token `('
bash: ` _items=$( cd "${1}"; ls -d .!(|.)?* 1>&3 ) # This requires extended glob'
The entire if
block executes as expected if I execute shopt -t extglob
before entering it. This is my current solution. However, this breaks the convention I'm trying to set across my environments. I'm trying to use the same .*
files across my machines, which also helps with quickly creating a consistent environment on a new machine.
What is causing the extra syntax check for the contents of the if
block?
if ... fi
block (including that glob expression) before it can begin executing it, and thereforeextglob
needs to be set before the beginning of theif
block. The same thing applies to using extended globs inside any complex command or even function definition. See my answer to "Case statement with extglob" on stackexchange. – Gordon Davisson Dec 26 '22 at 19:13