Search code examples
bashshcsh

if single-character filename exists within a string enclosed in [ ] entire string gets replaced with the character


I was making a one-time script, calling it just a, and I got a very surprising error; the script contained some ipv6-adresses in square brackets, one including the letter a.

I got a message saying a was not a valid ipv6 address. So I experimented, and I think I found a very obscure bug. Or square brackets have another meaning than I think.

Try this code, in bash, sh or csh

mkdir /tmp/temp123
cd /tmp/temp123
echo [123abc]
touch a
echo [123abc]

The output is

[123abc]
a

My conclusion is:

  • IF a file with a single-character filename exists in current directory

  • AND that character is anywhere between [ ]

  • AND there is whitespace outside [ ] ( x[abc]y doesn't work )

then the shell replaces the entire substring, including the [ ].

Two-(or more?)-character filenames are not affecting this.

WTF?!?


Solution

  • It is not a bug.

    Characters in square brackets is the part of glob matching. Try:

    cd /
    echo [abcd]*
    

    And if there is no files matched to the given mask then the mask printed as is.

    So you need to quote your values:

    mkdir /tmp/temp123
    cd /tmp/temp123
    echo "[123abc]"
    touch a
    echo "[123abc]"