I'm running a program that takes variable numbers of arguments with the same flag. For example
myprogram -args 'var1' 'var2' 'var3' 'var4'
myprogram -args 'var5' 'var6'
I have to launch this program several times with different sets of arguments provided in a test.txt file.
arg1 arg2 arg3
arg5 arg6
arg7
arg8 arg9 arg9 arg10
The program must be inside its own script to request resources in our HPCC.
while read p; do
launchmyprogram.sh "$p"
done < test.txt
I know I can use var1=$1
syntax inside launchmyprogram.sh to collect and allocate the variables, but this cannot handle variable number of arguments, and I'd have to create a script for each line. Is there a way to create a script in bash that takes variable numbers of arguments?
CodePudding user response:
Use arrays to store dynamically sized sequences of strings. Bash has two ways of reading input into an array:
readarray -t somearray
turns lines of an entire input file into array elements.read -a somearray
turns tokens of a single line of input into array elements.
In this case you can use the latter. Here’s a runnable MWE:
myprogram() {
local -i i
echo "Got ${#} arguments."
for ((i = 1; i <= $#; i)); do
echo "Argument No. ${i} is '${!i}'."
done
}
while read -ra args; do
myprogram -args "${args[@]}"
done <<-INPUT
arg1 arg2 arg3
arg5 arg6
arg7
arg8 arg9 arg9 arg10
INPUT
That way the arguments from each line are kept separate, as the output suggests:
Got 4 arguments.
Argument No. 1 is '-args'.
Argument No. 2 is 'arg1'.
Argument No. 3 is 'arg2'.
Argument No. 4 is 'arg3'.
Got 3 arguments.
Argument No. 1 is '-args'.
Argument No. 2 is 'arg5'.
Argument No. 3 is 'arg6'.
Got 2 arguments.
Argument No. 1 is '-args'.
Argument No. 2 is 'arg7'.
Got 5 arguments.
Argument No. 1 is '-args'.
Argument No. 2 is 'arg8'.
Argument No. 3 is 'arg9'.
Argument No. 4 is 'arg9'.
Argument No. 5 is 'arg10'.
CodePudding user response:
You can use $#
to query the number of arguments passed to launchmyprogram.sh
. Something like
if [ $# -eq 1 ]; then
echo "one argument"
elif [ $# -eq 2 ]; then
echo "two arguments"
elif [ $# -eq 3 ]; then
echo "three arguments"
else
echo "too many arguments"
exit 1
fi
CodePudding user response:
All bash scripts take a variable number of arguments, your question is about how to access them. The simplest method is:
for arg; do
my-cmd "$arg"
done
This repeats my-cmd
with each argument, individually. You can use this loop in launchmyprogram.sh
. You can also put the relevant code in a function, and use just the function inside the loop.
Parsing arguments from a file is more complicated. If the arguments aren't quoted for the shell, and don't contain spaces or wildcard characters ([]?*
), you could just unquote $p
in your example. It will be split on white space in to multiple arguments.
In this case you could also just parse the whole file in launchmyprogram.txt
:
for arg in $(<test.txt); do
my-cmd "$arg"
done