views:

217

answers:

4

I'm writing a cPanel postwwwact script, if you're not familiar with the script its run after a new account is created. it relies on the user account variable being passed to the script which i then use for various things (creating databases etc). However, I can't seem to find the right way to access the variable i want. I'm not that good with shell scripts so i'd appreciate some advice. I had read somewhere that the value i wanted would be included in $ARGV{'user'} but this simply gives "root" as opposed to the value i need. I've tried looping through all the arguments (list of arguments here) like this:

#!/bin/sh
for var
do
    touch /root/testvars/$var
done

and the value i want is in there, i'm just not sure how to accurately target it. There's info here on doing this with PHP or Perl but i have to do this as a shell script.

EDIT Ideally i would like to be able to call the variable by something other than $1 or $2 etc as this would create issues if an argument is added or removed

..for example in the PHP code here:

function argv2array ($argv) {
        $opts = array();
        $argv0 = array_shift($argv);

        while(count($argv)) {
                $key = array_shift($argv);
                $value = array_shift($argv);
                $opts[$key] = $value;
        }
        return $opts;
}
// allows you to do the following:
$opts = argv2array($argv);
echo $opts[‘user’];

Any ideas?

A: 

If it's passed as a command-line parameter to the script, it's available as $1 if it's first parameter, $2 for the second, and so on.

unwind
I'm not keen on this, what happens if an argument is added or removed
seengee
A: 

You can do the following:

#!/bin/bash

for var in $argv; do
  <do whatver you want with $var>
done

And then, invoke the script as:

$ /path/to/script param1 arg2 item3 item4 etc
MasterGaurav
+1  A: 

Why not start off your script with something like

ARG_USER=$1
ARG_FOO=$2
ARG_BAR=$3

And then later in your script refer to $ARG_USER, $ARG_FOO and $ARG_BAR instead of $1, $2, and $3. That way, if you decide to change the order of arguments, or insert a new argument somewhere other than at the end, there is only one place in your code that you need to update the association between argument order and argument meaning.

You could even do more complex processing of $* to set your $ARG_WHATEVER variables, if it's not always going to be that all of the are specified in the same order every time.

Tyler McHenry
+1  A: 

The parameters are passed to your script as a hash:

/scripts/$hookname user $user password $password

You can use associative arrays in Bash 4, or in earlier versions of Bash you can use built up variable names.

#!/bin/bash
# Bash >= 4
declare -A argv
for ((i=1;i<=${#@};i+=2))
do
    argv[${@:i:1}]="${@:$((i+1)):1}"
done
echo ${argv['user']}

Or

#!/bin/bash
# Bash < 4
for ((i=1;i<=${#@};i+=2))
do
    declare ARGV${@:i:1}="${@:$((i+1)):1}"
done
echo ${!ARGV*}  # outputs all variable names that begin with ARGV
echo $ARGVuser

Running either:

$ ./argvtest user dennis password secret
dennis

Note: you can also use shift to step through the arguments, but it's destructive and the methods above leave $@ ($1, $2, etc.) in place.

#!/bin/bash
# Bash < 4
# using shift (can use in Bash 4, also)
for ((i=1;i<=${#@}+2;i++))
do
    declare ARGV$1="$2"
    # Bash 4:  argv[$1}]="$2"
    shift 2
done
echo ${!ARGV*}
echo $ARGVuser
Dennis Williamson
the Bash < 4 script worked great, thanks!
seengee