1

Why when reading input with read, and the input is ??? the result is bin src?

$ read
???
$ echo $REPLY
bin src

Running bash on macOS.

Kusalananda
  • 333,661
YardenST
  • 247
  • 3
  • 9

1 Answers1

3

The data held in the variable REPLY is still ???, but the result from using the variable unquoted with echo, like you are doing, is the same as doing

echo ???

You need to double quote all variable expansions.

When you leave a variable expansion unquoted, two things happens:

  1. The value of the variable is split into multiple words. The splitting happens wherever a character is the same as one of the characters in $IFS (a space, tab and a newline by default). In your case, the result of the splitting is the same as before the splitting (the single word ???) if the value of $IFS is not modified.
  2. Each generated word undergoes filename generation, or "filename globbing". That means that if a word is a globbing pattern, which ??? is, any filenames matching that pattern will replace the pattern. The pattern ??? matches any three character long filename and you obviously have two of those in your current working directory.

Neither of these things happens if the variable expansion is double-quoted.

Example, recreating your issue and solving it:

$ ls
X11R6   games   lib     libexec mdec    ports   share   xobj
bin     include libdata local   obj     sbin    src
$ read
???
$ echo $REPLY
bin lib obj src
$ echo ???
bin lib obj src
$ echo "$REPLY"
???

Another example in the same directory as above, showing that the string that I input is split into two words (??? and s*) and that these then gets used as filename globbing patterns:

$ read
??? s*
$ echo $REPLY
bin lib obj src sbin share src
$ echo "$REPLY"
??? s*

Notice that src gets outputted twice as it matches both ??? and s*.

Related:

Short summary of the above questions and answers: Always double quote all expansions, unless you know exactly which ones don't need it or if you actually want to invoke splitting and globbing.

Kusalananda
  • 333,661