0

I'm trying to run this inside a bash script.

./configure --with-cc-opt='-O0 -g -Wno-error'

but with the '-O0 -g -Wno-error' part passed in as a variable. Note the above works just fine without the variable.

if I use this

CC_OPTS="'-O0 -g -Wno-error'"
./configure --with-cc-opt=${CC_OPTS}

it's like the value in the single quotes gets split up and ./configure ends up getting --with-cc-opt=-O0, -g and -Wno-error as separate arguments.

CC_OPTS="'-O0 -g -Wno-error'"
echo ${CC_OPTS}

prints out '-O0 -g -Wno-error', with the right single quotes.

CC_OPTS="'-O0 -g -Wno-error'"
echo --with-cc-opt=${CC_OPTS}

prints out --with-cc-opt='-O0 -g -Wno-error' which is correct too. But still ./configure receives them as separate arguments.

What am I doing wrong?

marathon
  • 7,881
  • 17
  • 74
  • 137
  • 2
    Literal quotes are not a substitute for syntactic quotes -- the distinction between the two is critical. See [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050). – Charles Duffy Sep 21 '17 at 04:32
  • 1
    BTW, http://shellcheck.net/ shows your bug, and `bash -x yourscript` accurately logs what's going on at runtime. (`echo` doesn't, but `echo` is useless -- worse than useless, actively misleading -- for figuring out quoting problems. Consider `printf '<%s>\n' --with-cc-opt=${CC_OPTS}` as more accurately showcasing the problem). – Charles Duffy Sep 21 '17 at 04:34
  • 1
    (if you aren't convinced that `echo` is useless, compare `echo "foo bar"` and `echo "foo" "bar"` -- obviously, these are two different command lines with different meanings, just as `ls "foo bar"` is looking for one file and `ls "foo" "bar"` is looking for two different files, but you wouldn't know that from the output of `echo`). – Charles Duffy Sep 21 '17 at 04:36
  • 1
    (By the way, as defined above, that's a regular shell variable, not an environment variable; a shell variable is stored in the shell's regular memory, whereas an environment variable additionally has a copy stored in the operating system's process metadata and is inherited by child processes, and can be created with `export` or, scoped to a single command, by prefixing `var=value` to it, or by programs calling `setenv()` to manipulate their own environment and, by extension, that of their children, or by programs explicitly specifying an environment when calling `execve()`). – Charles Duffy Sep 21 '17 at 04:38

1 Answers1

3

The code you're after is:

CC_OPTS="-O0 -g -Wno-error"
./configure --with-cc-opt="${CC_OPTS}"

You can't just put single quotes in a string and expect them to be interpreted. That's like putting + in a Java string and expect this to work:

String s = "1+1";
System.out.println(1+1); // print 2
System.out.println(s);   // prints 1+1 instead of 2

What you want is for --with-cc-opt=-O0 -g -Wno-error to be passed as a single parameter. All quotes are just there to convince the shell to make that happen, and no quotes should ever make it into the actual parameter.

that other guy
  • 116,971
  • 11
  • 170
  • 194