Why does bash “echo [t]” result in “t” not “[t]”

[] denotes a character class, and you have a file named t in your current directory.

The following should explain it further:

$ ls
$ echo [t]
[t]
$ touch t
$ echo [t]
t
$ echo [root]
t
$ touch r
$ echo [root]
r t

If you want to echo something within [], escape the [:

echo \[$var]

Observe the difference now:

$ echo \[root]
[root]

or, as Glenn Jackman points out, quote it:

$ echo '[root]'
[root]
$ echo "[root]"
[root]

Shell Command Language tells that the following characters are special to the shell depending upon the context:

*   ?   [   #   ~   =   %

Moreover, following characters must be quoted if they are to represent themselves:

|  &  ;  <  >  (  )  $  `  \  "  '  <space>  <tab>  <newline>

You could also use printf to determine which characters in a given input need to be escaped if you are not quoting the arguments. For your example, i.e. [s]:

$ printf "%q" "[s]"
\[s\]

Another example:

$ printf "%q" "[0-9]|[a-z]|.*?$|1<2>3|(foo)"
\[0-9\]\|\[a-z\]\|.\*\?\$\|1\<2\>3\|\(foo\)

Leave a Comment