Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to pass an empty string to a command line program in bash within a VARIABLE?

I have trouble using a command line executable. I need to pass a potentially empty string to a program from bash, but the string is stored in a bash variable.

The (minimal working example of the C++) program is:

// Compile with g++ main.cpp -o soexec

#include <iostream>

int main(int argc, char** argv) {
  // shows what the program arguments are
  for(size_t ind = 1 ; ind < argc; ++ind)
    std::cout << "  argv[" << ind << "]={" << argv[ind] << "}" << std::endl;

  // real application code should go here
  return EXIT_SUCCESS;
}

When I use the program without variables, I got the following, as expected:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

$ ./soexec --paramName ""
    argv[1]={--paramName}
    argv[2]={} # empty string, as wanted
$ EMPTY_VARIABLE=
$ ./soexec --paramName "${EMPTY_VARIABLE}"
    argv[1]={--paramName}
    argv[2]={} # empty string, as wanted

However, if the command lines arguments are stored in a variable, I get an issue

$ VARIABLE_NAME=
$ ARGS="--paramName $VARIABLE_NAME"
$ ./soexec $ARGS
  argv[1]={--paramName}
  # no argv[2]!

I also tried

$ VARIABLE_NAME=\"\"
$ ARGS="--paramName $VARIABLE_NAME"
$ ./soexec $ARGS
  argv[1]={--paramName}
  argv[2]={""} # this time the string is no longer empty, it contains the quote...

How can in pass a potentially empty string in bash to a command-line program ?

Note: this question has been marked as a duplicate of When should I wrap quotes around a shell variable?. However, it not only about quote in shell variable, it is about variable stored in another variable.

PS: for more context, my initial (and now resolved) problem was:
What's the best way to pass an empty string as argument to boost::program_options?

>Solution :

The problem is not really storing the argument in a variable, but expanding it before its actual use by including it in the $ARGS string.

So my first suggestion would be to avoid that string and passing the arguments directly to the program, when possible:

./soexec --paramName "$VARIABLE_NAME"

However, when this is not possible (or for any reason you want to use the ARGS variable), then it’s better to use a bash array (tutorial), instead of a string, so that each variable can be expanded individually. For this, you use "${your_array[@]}" ([@] to retrieve all elements and the quotes to keep the spaces in each, if present).

declare -a ARGS
ARGS[0]="--paramName"
ARGS[1]="$VARIABLE_NAME"
./soexec "${ARGS[@]}"

If you don’t like using the indices, you can also just use the += operator to append values to the array.

declare -a ARGS
ARGS+=("--paramName")
ARGS+=("$VARIABLE_NAME")
# equivalent to
# ARGS+=("--paramName" "$VARIABLE_NAME")
./soexec "${ARGS[@]}"
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading