Accessing a variable from ARGV
I am writing a cPanel postwwwact script in case you are not familiar with the script to run it after creating a new account. it relies on a user account variable that is passed to the script, which I then use for various things (creating databases, etc.). However, I cannot find the correct way to access the variable I want. I'm not that good at shell scripting, so I would appreciate some advice. I read somewhere that the value I wanted would be included in $ ARGV {'user'}, but that just gives "root", not the value I need. I've tried iterating over all arguments ( argument list 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 fine tune it. See here when doing this from PHP or Perl, but I have to do it as a shell script.
EDIT Ideally I would like to be able to call a variable with nothing more than $ 1 or $ 2, etc., as that would create problems if the argument was added or removed.
.. for example in 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 source to share
The parameters are passed to the 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 generated 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
Run:
$ ./argvtest user dennis password secret dennis
Note: you can also use shift
to pass through arguments, but this is destructive and the above methods 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
a source to share
Why not start from a script with something like
ARG_USER=$1
ARG_FOO=$2
ARG_BAR=$3
And then in your script refer to $ARG_USER
, $ARG_FOO
and $ARG_BAR
instead of $1
, $2
and $3
. Thus, if you decide to change the order of the arguments or insert a new argument somewhere other than the end, there is only one place in your code that needs to update the relationship between the order of the argument and the value of the argument.
You can do more complex processing $*
to set the variables $ARG_WHATEVER
if it is not always the case that they are all listed in the same order every time.
a source to share