Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 3 down vote accepted

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

share|improve this answer
    
Why recommend against the use of getopts? It's there. It works. It does option bundling. –  Gilles Mar 1 at 15:39
    
@Gilles - I wasn't saying not to use it, just that I generally don't. –  slm Mar 1 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 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 at 18:49

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.