Search code examples
bashargumentsquotingvariable-expansion

How to pass a variable args="foo bar=\"baz qux\"" as exactly *2* arguments?


Take the following script:

#!/bin/bash

function print_args() {
    arg_index=1
    while [ $# -gt 0 ]; do
        echo "$arg_index: $1"
        arg_index=$(expr $arg_index + 1)
        shift
    done
    echo
}

echo "print_args foo bar=\"baz qux\""
echo "-----------------------------------------------"
print_args foo bar="baz qux"

args="foo bar=\"baz qux\""

echo "print_args \$args (args=\"foo bar=\\\"baz qux\\\"\")"
echo "-----------------------------------------------"
print_args $args

echo "print_args \"\$args\" (args=\"foo bar=\\\"baz qux\\\"\")"
echo "-----------------------------------------------"
print_args "$args"

It outputs the following:

print_args foo bar="baz qux"
-----------------------------------------------
1: foo
2: bar=baz qux

print_args $args (args="foo bar=\"baz qux\"")
-----------------------------------------------
1: foo
2: bar="baz
3: qux"

print_args "$args" (args="foo bar=\"baz qux\"")
-----------------------------------------------
1: foo bar="baz qux"

The output I want to get is the following:

-----------------------------------------------
1: foo
2: bar="baz qux"

This is the result of print_args foo bar="baz quz". However, I need it to be the result of calling print_args with a single variable argument. I am ultimately trying to figure out how to pass multiple arguments to CMake within a shell script that is set up to run

cmake ${cmake_flags} ../${target}

Some of the options in cmake_flags need to be quoted because they contain spaces, but I overall want CMake to recognize multiple different options being passed to it, which doesn't happen if I quote cmake_flags.


Solution

  • Use array syntax instead, as follows:

    cmake_flags=( foo bar="baz qux" )
    
    cmake "${cmake_flags[@]}"