I have the following Z-shell script:

warnings="-Wall -Wextra -Wpedantic"
${compiler} ${warnings} ${standard} -o ${1} ${1}.cpp

This does not work as the ${warnings} variable appears to be seen as "-Wall -Wextra -Wpedantic" - that is one long warning with spaces, versus three separate warnings.

I did some searching and was able to get it to work with eval:

eval "${compiler} ${warnings} ${standard} -o ${1} ${1}.cpp"

However, I am confused as to why it is necessary, and also is there some other way to correct this issue.

EDIT: In addition to doing it as shown in Peter O. 's answer, I found that you can do:

setopt shwordsplit

to get the Z-shell to behave like other Bourne shell derivatives. As they say in their FAQ:

In most Bourne-shell derivatives, multiple-word variables such as

var="foo bar"

are split into words when passed to a command or used in a for foo in $var loop. By default, zsh does not have that behaviour: the variable remains intact. (This is not a bug! See below.) The option SH_WORD_SPLIT exists to provide compatibility.

  • 1
    Which shell are you using? – Gilles 'SO- stop being evil' Jul 26 '15 at 22:59
  • @Gilles I was using the z-shell. I just checked and the problem does not exist when run with bash. – Scooter Jul 27 '15 at 9:28
  • Answers do not go in questions. – JdeBP Jan 3 '20 at 7:18

Set your Warning options as an array. "${warnings[@]}" generates 3 individual words

warnings=(-Wall -Wextra -Wpedantic)

"${compiler}" "${warnings[@]}" "${standard}" -o "${1}" "${1}.cpp"

Or, if you find it more legible, you can create the array without -W's, and then add -W's via how you present the array on the command line.

warnings=( all extra pedantic )

"${compiler}" "${warnings[@]/#/-W}" "${standard}" -o "${1}" "${1}.cpp"
  • Thanks! I guess you figured out I was using the Z-shell. I just found out that it worked the string way with bash (tried in response to question above). – Scooter Jul 27 '15 at 9:47
  • Why doesn't putting quotes around ${warnings[@]/#/w} recreate the problem - that is a string with spaces getting passed to the shell? – Scooter Jul 27 '15 at 10:22
  • It seems that I can just do ${warnings} and the array gets expanded into 3 separate strings and the command works. – Scooter Jul 27 '15 at 11:29

You can also use $= to split a variable by $IFS:

${compiler} ${=warnings} ${standard} -o ${1} ${1}.cpp

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.