At some point in your work you may have to use the same script to run many different scenarios. Maybe different models with different data sets or something similar. If the code has many variables, directly modifying the code could be dangerous or at least boring. Therefore, it may be better to give the script some arguments when it is executed.
We can do it with getopts.
getops reads the arguments passed to the script, as follow:
script.sh -a argument_1 -b argument_2 -c argument_3
# or
script.sh -b argument_2 -c argument_3 -a argument_1
As you can see in the example, the order is not important, but it is mandatory to put the identifier before the argument (the letter after each “-“).
Let’s see a very simple example.
Suppose you have to run different models, stored in a list, many times and you want to save the results in different directories.
# list of models
echo "mod1
mod2
mod3" > mod_list.txt
# and just to test another one
echo "m1
m2
m3" > mod_list2.txt
We can do the job in this way (maybe not the best way):
#!/bin/bash
# default values
start=1
stop=5
mod_list="mod_list.txt"
# read the arguments
while getopts :s:f:m: option
do
case ${option} in
s) start=$OPTARG ;; # start the sequence
f) stop=$OPTARG ;; # stop the sequence
m) mod_list=$OPTARG ;; # list of models
esac
done
# Just to have the list of our arguments in the output.
echo "List of arguments:"
echo "start= $start"
echo "stop= $stop"
echo "mod_list= $mod_list"
# read the list of models
model=$(cat $mod_list)
# Process
for se in $(seq $start $stop);
do
for mod in $model;
do
# Make a directory for model and enter it
mkdir -p $mod
cd $mod
# Run the model
echo $se " $mod result" | tee -a results_$mod.txt
# Return to the original directory and do the same for the next model
cd ..
done
done
In this case we can pass to the script three arguments: -s , -f and -m; for three variables: start, stop and mod_list. start and stop will define a sequence and in mod_list we have the list of models.
The structure of the script that reads the arguments is:
# read the arguments
while getopts :s:f:m: option
do
case ${option} in
s) start=$OPTARG ;; # start the sequence
f) stop=$OPTARG ;; # stop the sequence
m) mod_list=$OPTARG ;; # list of models
esac
done
And just before it, we gave to the script the default values of the variables:
# default values
start=1
stop=5
mod_list="mod_list.txt"
If we put the default values after getopts, the ones we pass by arguments will overwrite.
To run the script:
# try without arguments
./myscript.sh
# Or passing different ones
./myscript.sh -m mod_file.txt -s 100 -f 150
./myscript.sh -s 56 -f 58 -m mod_list2.txt
Other commands in the script: