3

I want to use multiple instances of command line paramater such as the -d option used by PHP for passing PHP options. I am currently using the getopts command in bash.

With PHP invocation it would look like this:

php -f aPHPscript.php -d memory_limit=120M -d apc=1 -d max_execution_time=120

How would the multiple instances of the parameter be extracted in a bash script? Is there a bash command for doing that?

2 Answers 2

3

Bash doesn't typically care about the values of the arguments, it's more their ordering, and how they're separated on the command line, by default parsing them based on a space between each argument.

You can see this with a simple for loop construct in a shell script like so:

#!/bin/bash

echo ""
echo "ARGS: $@"

echo ""
echo "parsed args:"
for i in "$@"; do
    echo "$i"
done

Example

$ ./parse.bash -f aPHPscript.php -d memory_limit=120M -d apc=1 \
     -d max_execution_time=120

ARGS: -f aPHPscript.php -d memory_limit=120M -d apc=1 -d max_execution_time=120

parsed args:
-f
aPHPscript.php
-d
memory_limit=120M
-d
apc=1
-d
max_execution_time=120

In the above, each iteration through the loop is "peeling off" the next argument that was passed into the script parse.bash. So rather then use getopts you could always do something like this.

Using while + case

I typically don't use getopts and do things as you're inquiring about like so with a while loop using a case statement to parse the arguments as required.

$ more parse2.bash 
#!/bin/bash

while [[ $# > 1 ]]
do
key="$1"
shift

#  -f aPHPscript.php -d memory_limit=120M -d apc=1 
#+ -d max_execution_time=120

case $key in
    -f)
    f_ARG="$1"
    shift
    ;;
    -d)
    d_ARGS=( "${d_ARGS[@]}" "$1" )
    shift
    ;;
    *)
            # unknown option
    ;;
esac
done

echo "$f_ARG"
echo "${d_ARGS[@]}"

When we run it with your arguments we can see that it was able to parse your -d arguments into an array, $d_ARGS.

$ ./parse2.bash -f aPHPscript.php -d memory_limit=120M -d apc=1 \
      -d max_execution_time=120
aPHPscript.php
memory_limit=120M apc=1 max_execution_time=120

References

4
  • Why recommend against the use of getopts? It's there. It works. It does option bundling. Mar 1, 2014 at 15:39
  • @Gilles - I wasn't saying not to use it, just that I generally don't.
    – slm
    Mar 1, 2014 at 15:42
  • I want to use a function to extract the parameters I need and reinsert them back into the original script where those parameters are required. However it seems to me that $# variable is some kind of global that is permanently changed by shift command and manipulating it will affect the original script. Can it be copied to a separate variable to extract the required arguments?
    – vfclists
    Mar 1, 2014 at 16:46
  • @vfclists - when you shift you're popping the variables off of an array ($@). `$# reflects the index of the last element of that array.
    – slm
    Mar 1, 2014 at 18:49
2

You have to call getopts several times. You must take care what to do with the option arguments. You may use an index, write all arguments to -d to option_d[index_d++] so that you get an array. But that has nothing to do with getopts.

You must log in to answer this question.

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