This question already has an answer here:
There is weird thing i noticed today
If i have file by name i or o or e
and echo any string with any of the above character within square bracet - [] then it always prints only the character
$ touch i e o
$ ls -lrh
total 0
-rw-r--r-- 1 root root 0 May 23 08:24 o
-rw-r--r-- 1 root root 0 May 23 08:24 i
-rw-r--r-- 1 root root 0 May 23 08:24 e
$ echo [offline]
e i o
$ echo [online]
e i o
$ echo [error]
e o
$ echo [soap]
o
and if i remove the file everything works fine
$ rm -f e i o
$ ls
$ echo [offline]
[offline]
$ echo [online]
[online]
$ echo [error]
[error]
$ echo [soap]
[soap]
So what is the relation between echo and these file names ?
The shell performs pathname expansion on the command line arguments. Pathname expansion looks at each unquoted argument in turn and tries to replace it with a list of matching filenames. For this purpose the following wildcards apply:
*
means 0 or more characters, any characters;?
means 1 character, any character;[
<chars>]
means 1 character, one of the given <chars>.If one or more file names match, the command line argument is replaced with the list of matching file names. If no file names match, the command line argument is left as is.
So in your case:
[offline]
is an unquoted command line argument, whichIncludes the wildcard
[
...]
, andThe files
e
,i
ando
match the wildcard, soThe shell replaces the argument with the list of matching file names.
Morality: Always but always quote the arguments which you don't want the shell to expand. Always say
echo '[offline]'
, never sayecho [offline]
.