Yet another command line 'spaces in arguments' this really 2022?


This has been driving me nuts all morning!

Why does this work OK?

export CHECKOUT_DIR=openxr-checkout
export BUILD_DIR=openxr-build
cmake -S "$CHECKOUT_DIR" -B "$BUILD_DIR" -DDYNAMIC_LOADER=OFF -G "Visual Studio 17 2022"

But this doesn’t?

export BUILD_CONFIG="-DDYNAMIC_LOADER=OFF -G \"Visual Studio 17 2022\""
CMake Error: Could not create named generator "Visual
CMake Warning:
  Ignoring extra path from command line:


It’s like something’s ignoring the quotes. If I run the first ‘plain’ version without quotes I get a similar error, only also without quotes, ie: ‘Could not create named generator Visual’.

If echo $BUILD_CONFIG I get the expected (IMO) result, ie: quotes have been properly escaped:

-DDYNAMIC_LOADER=OFF -G “Visual Studio 17 2022”

I am of course on Windows and using the version of bash that comes with git, which may have something to do with it.

This may well be nothing to do with cmake, but it’s an oddity I’ve never encountered before.

Any ideas?

cmake version 3.23.2


It has nothing to do with CMake and everything to do with the shell…
I was frustrated by the same thing some time ago and did a deeper research that lead to one conclusion: JUST DON’T.
Unfortunately normal rules regarding argument passing do not apply when using variables on the command line. It’s next to impossible to get quoted arguments working this way.

Depending on the shell in use (looks like a bash?), the escape markers are different. I would recommend using set -x to have the shell output what it sees before execution (if it is indeed a bash-alike).

OK, I’ve had a play around with this and it’s definitely a limitation of shell(s) IMO.

I’ve tried it now in Manjaro bash, fish and Windows git bash, and in all cases shell can’t tell the difference between an ‘argument separating’ space and a ‘real space in arg/filename’ when interpolating vars. Simplest example I could come up with:

mkdir "test dir"
export TEST="-l \"test dir\""
ls $TEST

No matter how I try to escape the space in ‘test dir’, shell always splits $TEST into 3 args to ls. I confirmed this with a little printf argv app.

Moral of the story is probably to never put multiple command args in a var, unless you know for sure that none of them contain space chars?


You can use the bash array extension:

args=("arg1" "arg 2")
ls "${args[@]}"

Cool, that does seem to work thanks.