1

When I printout the content of a file with echo $(cat /path/to/filename), it list my files and directions too. But when I do with printf "$(cat /path/to/filename)\n" it works fine.

I tried also saving it into a variable content='cat /path/to/filename' (also content=$(cat /path/to/filename) and then print by echo $content, but I getting the same result (list files and directions).

I want to store the content of the file into variable and pass the variable into my script as an input to next command.

Note that the content of my file has special character * in it.

2 Answers 2

7

Because after performing command substitution, the shell perform word splitting (or field splitting) on the result if you don't quote them.

POSIX defined word expansion as:

The order of word expansion shall be as follows:

  1. Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution), and arithmetic expansion (see Arithmetic Expansion) shall be performed, beginning to end. See item 5 in Token Recognition.

  2. Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.

  3. Pathname expansion (see Pathname Expansion) shall be performed, unless set -f is in effect.

  4. Quote removal (see Quote Removal) shall always be performed last.

In your case, * matched all thing in current working directory. You must quote the result to get the expected output:

echo "$(cat /path/to/fileName)"
3

Quote it:

$ echo "*" >> test
$ echo $(cat test)
bash43-001 bash43-002 bash43-003 bash43-004 bash43-005 test
$ echo "$(cat test)"
*

As a first rule, always quote command substitution.

The bare * will get expanded in bash, unless you turn off globbing (set -f or setopt noglob) or quote/escape it: "*" \*. For command output, it's always best to use quoting.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .