Home > Enterprise >  Passing variable number of arguments to a shell script
Passing variable number of arguments to a shell script

Time:10-21

I am building a script (linux bash) where I need to pass a certain number of arguments, it can be 7 or 8 arguments.

If I pass 7 arguments I will do it like this:

my_script.sh

!/bin/bash

arg1=$1
arg2=$2
arg3=$3
arg4=$4
arg5=$5
arg6=$6
arg7=$7
#Do other stuff after this

and I run it like this: ./my_script.sh 1 2 3 4 5 6 7

I want to be able to add an optional 8th parameter into this script. So the idea is to run the script with this 8th parametes sometimes and the rest of the time only with 7 parameters. How can I do this?

CodePudding user response:

You could do something like this:

if [[ $8 != '' ]]
then
  # do something
fi

Also, if you do

arg8=$8

and if there is no eighth arg, arg8 will just remain empty.

CodePudding user response:

Another thought. After you assign the first 7 args, use shift 7 to clear them from the positional parameters. Then, any extra parameters are in "$@" and the number is in $#

arg1=$1
arg2=$2
arg3=$3
arg4=$4
arg5=$5
arg6=$6
arg7=$7

shift 7

echo "There are $# extra parameters"
for arg in "$@"; do
    echo "-> $arg"
done

CodePudding user response:

You could check the value of $#, something like.

#!/usr/bin/env bash

if (($# == 8)); then
  printf '%d arguments given\n' "$#"
elif (($# > 8)); then
  printf '%d is greater than 8\n'  "$#"
elif (($# < 8)); then
  printf '%d is  Less than 8\n' "$#"
fi

To test that script.

my_script {1..8}

Output

8 arguments given

my_script {1..87}

Output

87 is greater than 8

my_script {1..7}

Output

7 is  Less than 8

CodePudding user response:

That's a lot of arguments. Are they all necessary every time? Can you default some?

Basically, I see three primary cases for this.

  1. You have a list of fixed-position required arguments. If they are all truly required, and you can never assume default values for any of them, then positional is actually good as it simplifies your coding... but as soon as you introduce optional arguments, you should seriously start considering getopts.

  2. if you have exactly and only one optional argument, then just assign arg8=$8 and don't worry about it - but as soon as you have two, then you really need to think about the implications. If you need $9 but don't really care about $8 then you have to pass in a dummy value to fill $8 for there to be a $9. Don't go there.

  3. in most cases, unless a script is really simple (and mine almost never are), you should use getopts.

Let's say that you're writing a telecom script that sums minutes of use. The script absolutely requires 3 arguments from user - for our example, say you need $state, $mmyy and $stream to identify input files by state and month/year, and local or long-distance. (You could always just pass that as $STMMYYLT or some such to reduce it to one argument if that's your taste, but generally, let a thing be a thing.)

With those, you can run it and get total minutes. Great.

But sometimes you need them broken out by account. Sometimes means an option argument. -s for --summarize changes the accumulation and output.

Sometimes you only need a specific account. You could always pipe the result through a grep or something, but if you can skip processing of 99.999% of a multi-gigabyte file by adding one more argument, I think that's worth it, so let's add a -a for --account option. If you give it an account, it will ignore everything else.

When designing, always thing in terms of the help screen that gives you usage instructions. It will really help your design to think of these things ahead of time. (Maybe that means a -h for --help is a good idea too...)
There are some guidelines on standard formatting such as this post or this wiki.

So, if you feed it an unacceptable set of arguments (including none), or specifically request --help, it should spit out a usage message and exit.

This gives you a guide for writing code. You can edit it as you figure out more.

  • Related