Inside a bash script function, I need to work with the command-line arguments of the script, and also with another list of arguments. So I'm trying to pass two argument lists to a function, the problem is that multi-word arguments get split.
function params()
{
for PARAM in $1; do
echo "$PARAM"
done
echo .
for ITEM in $2; do
echo "$ITEM"
done
}
PARAMS="$@"
ITEMS="x y 'z t'"
params "$PARAMS" "$ITEMS"
calling the script gives me
myscript.sh a b 'c d'
a
b
c
d
.
x
y
'z
t'
Since there are two lists they must be passed as a whole to the function, the question is, how to iterate the elements while respecting multi-word items enclosed in single quotes 'c d' and 'z t'?
The workaround that I have (see below) makes use of BASH_ARGV so I need to pass just a single list to the function. However I would like to get a better understanding of what's going on and what's needed to make the above work.
function params()
{
for PARAM in "${BASH_ARGV[@]}"; do
echo "$PARAM"
done
echo .
for ITEM in "$@"; do
echo "$ITEM"
done
}
params x y 'z t'
calling the script gives me
myscript.sh a b 'c d'
c d
b
a
.
x
y
z t
... Which is how I need it (except that first list is reversed, but that would be tolerable I guess)
You can pass more than one argument to your bash script. In general, here is the syntax of passing multiple arguments to any bash script: script.sh arg1 arg2 arg3 … The second argument will be referenced by the $2 variable, the third argument is referenced by $3 , .. etc.
We can use the getopts program/ command to parse the arguments passed to the script in the command line/ terminal by using loops and switch-case statements. Using getopts, we can assign the positional arguments/ parameters from the command line to the bash variables directly.
So as far as I can tell, %% doesn't have any special meaning in a bash function name. It would be just like using XX instead. This is despite the definition of a name in the manpage: name A word consisting only of alphanumeric characters and under- scores, and beginning with an alphabetic character or an under- score.
Syntax for defining functions: To invoke a function, simply use the function name as a command. To pass parameters to the function, add space-separated arguments like other commands. The passed parameters can be accessed inside the function using the standard positional variables i.e. $0, $1, $2, $3, etc.
function params()
{
arg=("$@")
for ((i=1;i<=$1;i++)) ;do
echo "${arg[i]}"
done
echo .
for ((;i<=$#-$1+2;i++)) ;do
echo "${arg[i]}"
done
}
items=(w x 'z t')
params $# "$@" "${items[@]}"
Assuming you call your script with args a b 'c d'
, the output is:
a
b
c d
.
x
y
z t
Peter.O's answer above works fine, and this is an addendum to it, with an example.
I needed a function or script that would take multi-word arguments, that would then be used to search the list of running processes and kill those that matched one of the arguments. The following script does that. The function kill_processes_that_match_arguments
only needs one for
loop, because my need was only to iterate over the set of all arguments to the function. Tested to work.
#!/bin/bash
function kill_processes_that_match_arguments()
{
arg=("$@")
unset PIDS_TO_BE_KILLED
for ((i=0;i<$#;i++))
do
unset MORE_PIDS_TO_KILL
MORE_PIDS_TO_KILL=$( ps gaux | grep "${arg[i]}" | grep -v 'grep' | awk '{ print $2 }' )
if [[ $MORE_PIDS_TO_KILL ]]; then
PIDS_TO_BE_KILLED="$MORE_PIDS_TO_KILL $PIDS_TO_BE_KILLED"
fi
done
if [[ $PIDS_TO_BE_KILLED ]]; then
kill -SIGKILL $PIDS_TO_BE_KILLED
echo 'Killed processes:' $PIDS_TO_BE_KILLED
else
echo 'No processes were killed.'
fi
}
KILL_THESE_PROCESSES=('a.single.word.argument' 'a multi-word argument' '/some/other/argument' 'yet another')
kill_processes_that_match_arguments "${KILL_THESE_PROCESSES[@]}"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With