2

The bash-5.0 manual in section 3.5.8 states the following.

After word splitting, unless the -f option has been set (see The Set Builtin), Bash scans each word for the characters ‘*’, ‘?’, and ‘[’. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern (see Pattern Matching). If no matching filenames are found, and the shell option nullglob is disabled, the word is left unchanged. If the nullglob option is set, and no matches are found, the word is removed.

However, in my shell, activating nullglob it seems that filename expansion kicks in also in the following case.

$ echo ${BASH_VERSION}
5.0.0(1)-release
$ shopt -s nullglob
$ FOO="/home/smith"
$ echo ${FOO//\//\\\/}

$ echo "${FOO//\//\\\/}"
\/home\/smith

Interestingly, using an older bash version I have available, a different behaviour occurs.

$ echo ${BASH_VERSION}
4.3.30(1)-release
$ shopt -s nullglob
$ FOO="/home/smith"
$ echo ${FOO//\//\\\/}
\/home\/smith
$ echo "${FOO//\//\\\/}"
\/home\/smith

Question

I would have expected no filename expansion to occur. Can you explain why echo ${FOO//\//\\\/} does not print anything with bash 5.0?

4
  • 2
    Yes, it's been the subject of numerous bug reports. Some posit that it's what POSIX currently requires. There have been long discussions on the austin-group mailing list about it, some arguing that it should be even more explicitly mandated. Thankfully, the consensus has since gone in the other direction which would make that behaviour of bash non-compliant (but backslashes in the result of unquoted expansion still required to be treated as an escape operator provided the expansion contains at least one *, ?, or [, which is still not what most implementations do). Jul 3, 2020 at 13:21
  • I'm glad to see that bash is going to revert it in 5.1. Jul 3, 2020 at 13:27
  • 3
    If you're really bored and have a few dozen hours to spare, you can read the discussions at austingroupbugs.net/view.php?id=1234 (full disclosure: "stephane" is me there) and mail-archive.com/austin-group-l@opengroup.org/msg03630.html (for the main thread, there have been more). Jul 3, 2020 at 13:37
  • Indeed, when I found out that it was going to be reverted, I looked for the discussion, but I could not find it. Hence, thanks for the links! :) Jul 3, 2020 at 13:41

1 Answer 1

1

Indeed, after some more research, it turned out that this was reverted afterwards in v5.1-alpha.

$ echo ${BASH_VERSION}
5.1.0(1)-alpha
$ shopt -s nullglob
$ FOO="/home/smith"
$ echo ${FOO//\//\\\/}
\/home\/smith
$ echo "${FOO//\//\\\/}"
\/home\/smith

which is what I was personally expecting.

This seems also to fix different cases (thanks Stéphane for pointing it out):

$ echo ${BASH_VERSION}
5.1.0(1)-alpha
$ a='/\x' bash -O nullglob -c 'echo $a'
/\x
1
  • Note that it was not reverted in 5.0. a='/\x' bash -O nullglob -c 'echo $a' still outputs nothing unless there's a /x file. The change you're linking to is from before the 5.0 release. The change that your output demonstrates is potentially a side-effect of patch 003 to address lists.gnu.org/archive/html/bug-bash/2019-01/msg00276.html Jul 3, 2020 at 13:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.