2

I have a script count_args that counts arguments:

#!/bin/sh
echo $#

If I call it with these options, it tells me it gets two arguments:

$ ./count_args --options '1 2'
2

But if I construct the arguments in a script test_args like so:

#!/bin/sh
ARGS="--options '1 2'"
./count_args ${ARGS}

...I get the result:

$ ./test_args 
3

Why is the '1 2' being split in the script? How can I avoid this in a POSIX compliant way, from the calling script? Is it possible to still store arguments in variables somehow so that I can separate them in more complex scripts (eg. having ARGS_1 and ARGS_2)?

Note that my /bin/sh is dash.

1

1 Answer 1

3

In your first case, the arguments passed to count_args were interpreted by the shell, the shell saw two words --options and 1 2 then passed them to count_args.

With second case, Inside double quotes, all characters except $ and \ are treated as literal. It's too late for the shell to interpret the single quotes, the shell saw the content of $ARGS variable as a long string --options '1 2', all characters as literal and have no special meaning to the shell.

Using ${ARGS} without double quotes made it subjected to fields splitting and filename expansion. With default value of IFS, you got three separated words: --options, '1 and 2'.

The best way to archive this is using "$@":

#!/bin/sh

set -- --options '1 2'

./count_args "$@"
3
  • So I've updated my question to be a little more specific: is there a way to do this using variables to separate various options? Otherwise I could just write ./count_args --options '1 2' right there in the script.
    – detly
    Commented Feb 14, 2016 at 7:51
  • I don't want to bait and switch though, so you get the tick because you answered the question I actually asked, as opposed to the one in my head.
    – detly
    Commented Feb 14, 2016 at 8:18
  • @detly How do I store a command in a variable? Commented Feb 14, 2016 at 21:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .