2

I'm trying to store a command string in a variable for later execution. The problem is that the command includes a parameter argument with whitespace. When the command is executed, instead of seeing the argument as a single string, the shell interprets it as two, including the double-quote characters:

Example:

$ CMD_CMAKE="cmake -G \"MSYS Makefiles\" ../../source/poppler-0.79/"

$ ${CMD_CMAKE} CMake Error: Could not create named generator "MSYS

I need to pass -G "MSYS Makefiles" to the cmake command. Instead, -G \"MSYS and Makefiles\" are being passed.

I have tried all of the following with no success:

$ CMD_CMAKE='cmake -G "MSYS Makefiles" ../../source/poppler-0.79/'

$ CMD_CMAKE="cmake -G 'MSYS Makefiles' ../../source/poppler-0.79/"

$ CMD_CMAKE="cmake -G MSYS\ Makefiles ../../source/poppler-0.79/"

$ CMD_CMAKE="cmake -G MSYS\ Makefiles ../../source/poppler-0.79/"

$ GEN="MSYS Makefiles" && CMD_CMAKE="cmake -G ${GEN} ../../source/poppler-0.79/"

$ GEN="MSYS Makefiles" && CMD_CMAKE="cmake -G "${GEN}" ../../source/poppler-0.79/"

$ CMD_CMAKE=$(echo "cmake -G "MSYS Makefiles" ../../source/poppler-0.79/")

$ CMD_CMAKE=$(echo 'cmake -G "MSYS Makefiles" ../../source/poppler-0.79/')

I have done some searching around on Google, but I am not finding any answers. Perhaps because I am not using the correct terminology.

Edit: I'm sorry, I think I should have posted this question on stackoverflow.com.

  • 1
    It seems like you want a function instead. – jesse_b Aug 02 '19 at 21:23
  • 3
    Also no you should not post on stackoverflow. You should read the linked duplicate because it will solve your issue. – jesse_b Aug 02 '19 at 21:23
  • 3
    You'll get the same answer on SO: Complex commands cannot be stored in simple variables. In addition to the linked answers, have a look at "I'm trying to put a command in a variable, but the complex cases always fail!" – John1024 Aug 02 '19 at 21:34
  • @Jesse_b Oh, I'm sorry. I glanced at the title of the linked answer & thought it was one that I had already read. Thank you very much. In this case, I like the array variable & am going to use that.

    Should this question be deleted?

    – AntumDeluge Aug 02 '19 at 21:37
  • 3
    @AntumDeluge: No it is not necessary to delete the question. It is likely to help future users with the same problem, if their search brings them to this question it will then bring them to the linked question as well. Also in the future if your question gets closed as a duplicate but is not in fact a duplicate you can explain why it isn't and it will be reopened. – jesse_b Aug 02 '19 at 21:41
  • 1
    And @John1024 Thank you too. That link was helpful as well. – AntumDeluge Aug 02 '19 at 21:52
  • Turns out, I will probably have to use a function as I am having the same problem with an array. – AntumDeluge Aug 02 '19 at 21:58
  • 1
    @AntumDeluge Very good. Generally, a function is the best & most-flexible method for this problem. – John1024 Aug 02 '19 at 21:59
  • 3
    @AntumDeluge If you have the same problem with an array, you may want to ask a separate question about that. It may be something simple that just needs a minor correction. With the full command in an array, e.g. array=(cmake -G "MSYS Makefiles" ../../source/poppler-0.79/), you execute it with "${array[@]}" (note the syntax and the quotes). – Kusalananda Aug 02 '19 at 22:05
  • 1
    @Kusalananda Thank you! That was my problem, I wasn't using quotes when I executed. "${CMD_CMAKE[@]}" worked. :) – AntumDeluge Aug 02 '19 at 22:13
  • 1
    I don't see why you couldn't do it the first way but use eval "${CMD_CMAKE}" instead of ${CMD_CMAKE} alone instead. – frabjous Jun 23 '22 at 19:19
  • @frabjous Thank you, that works. That is why I asked this question. :) – AntumDeluge Jun 23 '22 at 23:00

1 Answers1

0

Thanks to jesse_b & Kusalananda for the help in finding this solution.

It is actually pretty simple. To store the command & its parameters, put them in an array, enclosing any parameters with whitespace within double quotes:

CMD_CMAKE=(cmake -G "MSYS Makefiles" ../../source/poppler-0.79/)

To execute it, the variable should be enclosed within double quotes:

"${CMD_CMAKE[@]}"

Another solution mentioned by frabjous is to use the eval command:

CMD_CMAKE="cmake -G \"MSYS Makefiles\" ../../source/poppler-0.79/"
eval ${CMD_CMAKE}