0

I want to store the contents of a file in a bash shell variable. This works fine:

$ cat hello
Hello, world!
$ F=hello
$ Q=$(cat $F)
$ echo $Q
Hello, world!

However, if the file contains an asterisk, the asterisk is replaced by a list of all files in the current directory.

How can I quote the filename to protect the asterisk? Or otherwise load the file into the shell variable?

I am aware of this question, but it doesn't work for files that contain an asterisk.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
user448810
  • 17,381
  • 4
  • 34
  • 59
  • The next question: what if the _filename_ contains a space? `mv hello "hello world"; F="hello world"` -- what happens when you do `Q=$(cat $F)` ? – glenn jackman Apr 06 '21 at 21:08
  • Note, bash has a builtin way to read a file into a variable: `Q=$(<"$F")` -- documented in [3.5.4 Command Substitution](https://www.gnu.org/software/bash/manual/bash.html#Command-Substitution) – glenn jackman Apr 06 '21 at 21:11
  • Always run problem scripts through https://shellcheck.net – Shawn Apr 06 '21 at 21:57

1 Answers1

4

Q contains the asterisk. It is the unquoted expansion of $Q that replaces the * with a list of files.

$ Q="*"
$ echo $Q
<list of files>
$ echo "$Q"
*

The right-hand side of an assignment is not subject to path name expansion, so Q=* would work as well, and the command substitution used to read from the file is also not affected. Q=$(cat hello) works fine: you just need to quote the expansion of Q.

chepner
  • 497,756
  • 71
  • 530
  • 681