Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -fcf-protection -O2 -Wall -U_FORTIFY_SOURCE
-D_FORTIFY_SOURCE=3 -fstack-protector-strong -funwind-tables
-fasynchronous-unwind-tables -fstack-clash-protection
-Werror=return-type -flto=auto -g -D_GNU_SOURCE -DRECYCLES_PIDS -Wall
-g -Wuninitialized -Wextra -Wno-switch-enum -Wno-unused-variable
-Wno-unused-parameter -Wno-parentheses -ftree-loop-linear -pipe
-DBNC382214=0 -DIMPORT_FUNCTIONS_DEF=0
-DDEFAULT_LOADABLE_BUILTINS_PATH='/usr/lib64/bash'
uname output: Linux uefi 7.0.10-2-default #1 SMP PREEMPT_DYNAMIC Sat May
23 12:09:09 UTC 2026 (bb95589) x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-suse-linux-gnu
Bash Version: 5.3
Patch Level: 9
Release Status: release
Description:
Consider:
$ ls *
* x
$
So, two files - the first with the name '*', the second irrelevant.
$ bar='\**'
$ ls $bar
*
$
So far so good - pathname expansion produces expected result. In the
pattern "\*" matches the literal "*".
$ bar='\*'
$ ls $bar
ls: cannot access '\*': No such file or directory
$
Oops. Why it suddenly attempts to match *two* characters "\*" instead of
just one literal "*"?
It is even more confusing as in other places where patterns are used the
"\*" pattern apparently works correctly:
$ foo='abc:*'
$ echo ${foo%:$bar}
abc
$ [[ $foo == abc:$bar ]] && echo yes || echo no
yes
$
Repeat-By:
Assign a glob pattern with all special characters escaped by the
backslash ('\') and use this variable on the command line. Observe that
shell does not remove backslashes from the pattern so the result does
not match the existing files.
$ touch '***'
$ foo='\*\*\*'
$ ls $foo
ls: cannot access '\*\*\*': No such file or directory
$ ls '***'
***
$