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.
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
.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.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.