I am trying to pass bash user input read using the read command to an external application, as if what the user wrote were arguments in bash.
In the following example, I’ve used a function rather than an external application, but that should be irrelevant. This is the script I am using:
foo() { while [ "$#" -gt 0 ]; do echo "$1"; shift; done }
read -p "Write something: " bar
foo "${bar}"
foo ${bar}
What I write when I am asked to write something:
"a b" "c d" e\ f g\"h
What I expect to see as output:
a b
c d
e f
g"h
What I actually see: (the first line is first call to foo(), the rest of the lines are from the second call)
"a b" "c d" e f g"h
"a
b"
"c
d"
e
f
g"h
If you run
set -xbefore you start, bash will echo the commands as it’s trying to run them. In particular, you can see that bash is expanding $bar before it gets passed to foo():The answer is to use eval, however this isn’t quite as straightforward as it might seem:
In this case, you need to escape both the quote and the backslash: