Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to substitute quoted, multi-word strings as arguments?

I'm trying to substitute a string variable, containing multiple quoted words, as a parameter to a command.

Thus, given the following example script (Note the -x in the shebang, which causes the output to be logged to stderr),

#!/bin/bash -x

myArg="\"hello\" \"world\""
echo "string is:" $myArg

exit

Which gives us,

+ myArg='"hello" "world"'
+ echo 'string is:' '"hello"' '"world"'
string is: "hello" "world"
+ exit


Line two shows what is actually passed to the command; bash has added single quotes to each word in the string. If I instead, thusly, quote "$myArg", the same occurs but for the whole string rather than each word.

Now, imagine that instead of echo, we are passing the string to a program where some of the arguments need to be quoted patterns, such as "*" (which mustn't be expanded by the shell).

To clarify, I don't want the single quotes added at all during the expansion. How might I achieve this?

like image 243
Tim Morgan Avatar asked Feb 28 '12 15:02

Tim Morgan


2 Answers

Don't use quotes, use an array (see BashFAQ #050):

$ myArgs=("hello" "world" "multiword arg with * ?")
+ myArgs=("hello" "world" "multiword arg with * ?")
$ echo "${myArgs[@]}"
+ echo hello world 'multiword arg with * ?'
hello world multiword arg with * ?

If it really needs to be in the form of quoted strings within a string, you're either going to have to use something like eval "echo $myArg" (which can cause some really nasty bugs, if you aren't careful) or parse it yourself (which is going to be difficult).

like image 89
Gordon Davisson Avatar answered Oct 22 '22 10:10

Gordon Davisson


If you want to pass a variable value as a parameter (99% of cases on SO), simply use proper quoting:

arg="foo bar"
command "$arg"

If you want to pass several arguments, use arrays:

args=("foo bar" "baz ban" bay)
command "${args[@]}"
like image 35
l0b0 Avatar answered Oct 22 '22 11:10

l0b0