Home > Blockchain >  Is there a way to pass multiple argument as a single string in bash?
Is there a way to pass multiple argument as a single string in bash?

Time:06-09

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
  • Related