Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash script echo is performing a strange substitution

Realizing bash is very picky about double quotes, single quotes, brackets etc. -- I ran across a strange behavior today and can't explain it. The problem itself is easy to avoid but I don't understand the cause. I'm interested to understand WHY this happened just to improve my bash knowledge.

Here is a shortened example -- contents of file test.sh:

msg="Usage: command password [dbhost] [database] [user] [query] [filetag]"
echo $msg

Then run:

sh test.sh

I expected the output would be:

Usage: command password [dbhost] [database] [user] [query] [filetag]

However what I got was:

Usage: command password [dbhost] [database] [user] y [filetag]

If I change the word "query" to "querx", that part of the output becomes "x".

If I change the word "query" to "xuery", that part of the output becomes "x y".

If I change the word "query" to "xuerx", that part of the output becomes "x x".

There are no local or environment variables with names like query, querx etc.

This is on RedHat. Any ideas?

like image 567
Chris Johnson Avatar asked May 26 '26 12:05

Chris Johnson


1 Answers

The sequence of word expansions for a Bourne compatible shell is

  1. Tilde Expansion
  2. Parameter Expansion
  3. Command Substitution
  4. Arithmetic Expansion
  5. Field Splitting
  6. Pathname Expansion
  7. Quote Removal

So after parameter expansion for $msg, the pathname expansion finds [query] which looks for a file called q, u, e, r or y. You have a file named y, right?

Note that this behavior depends on the setting of the f option. With set -f the pathname expansion is not performed, while with set +f it is.

Of course you could double quote the echo arg as well, since pathname expansion is not performed on quoted words.

like image 111
Jens Avatar answered May 30 '26 04:05

Jens



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!