I am trying to improve a script called moduletest.sh
such that it can process both long and short command lines options.
#!/bin/bash
# Initialize variables
nsamps=""
scenario=""
pyear_start=""
pyear_end=""
pyear_step=""
baseyear=""
# Parse command line arguments
while getopts ":h-:n--:s--:p--:e--:t--:b--" opt; do
case $opt in
h) # Display help message and exit
cat <<EOF
usage: moduletest.sh [-h] [-n NSAMPS] [-s SCENARIO] [-p PYEAR_START]
[-e PYEAR_END] [-t PYEAR_STEP] [-b BASEYEAR]
modules.txt
optional arguments:
-h, --help show this help message and exit
-n NSAMPS, --nsamps NSAMPS
number of samples (default: 500)
-s SCENARIO, --scenario SCENARIO
scenario (default: ssp585)
-p PYEAR_START, --pyear_start PYEAR_START
projection year start (default: 2020)
-e PYEAR_END, --pyear_end PYEAR_END
projection year end (default: 2100)
-t PYEAR_STEP, --pyear_step PYEAR_STEP
projection year step (default: 10)
-b BASEYEAR, --baseyear BASEYEAR
base year (default: 2005)
positional arguments:
modules.txt file with module_set and module values
EOF
exit 0
;;
n) nsamps="$OPTARG"
;;
s) scenario="$OPTARG"
;;
p) pyear_start="$OPTARG"
;;
e) pyear_end="$OPTARG"
;;
t) pyear_step="$OPTARG"
;;
b) baseyear="$OPTARG"
;;
:) # Display error message and exit for missing required argument
echo "Error: Option -$OPTARG requires an argument." >&2
exit 1
;;
\?) # Display error message and exit for invalid option
echo "Error: Invalid option -$OPTARG" >&2
exit 1
;;
esac
shift # Shift positional arguments to the left
done
# Shift positional arguments
shift $((OPTIND-1))
# Get the remaining positional arguments
modules_file="$1"
# Check for required modules.txt file
if [ -z "$modules_file" ]; then
echo "Error: Missing required modules.txt file" >&2
exit 1
fi
# Set default values if not specified by user
nsamps=${nsamps:-500}
scenario=${scenario:-ssp585}
pyear_start=${pyear_start:-2020}
pyear_end=${pyear_end:-2100}
pyear_step=${pyear_step:-10}
baseyear=${baseyear:-2005}
# Print options
echo "NSAMPS = $nsamps"
echo "SCENARIO = $scenario"
echo "PYEAR_START = $pyear_start"
echo "PYEAR_END = $pyear_end"
echo "PYEAR_STEP = $pyear_step"
echo "BASEYEAR = $baseyear"
echo "MODULES_FILE = $modules_file"
However, the options are not applied to the script. For example,
./moduletest.sh --nsamps 1000 modules.txt
gives the same output as
./moduletest.sh modules.txt
./moduletest.sh.sh -n 1000 modules.txt
NSAMPS = 500
SCENARIO = ssp585
PYEAR_START = 2020
PYEAR_END = 2100
PYEAR_STEP = 10
BASEYEAR = 2005
./moduletest.sh.sh.sh --nsamps 1000 modules.txt
NSAMPS = 500
SCENARIO = ssp585
PYEAR_START = 2020
PYEAR_END = 2100
PYEAR_STEP = 10
BASEYEAR = 2005
MODULES_FILE = modules.txt
./moduletest.sh.sh.sh modules.txt
NSAMPS = 500
SCENARIO = ssp585
PYEAR_START = 2020
PYEAR_END = 2100
PYEAR_STEP = 10
BASEYEAR = 2005
MODULES_FILE = modules.txt
It looks like there is an issue with the way the command line arguments are being parsed. Any idea how to fix this? Ideally, /moduletest.sh should recognize both a single dash (e.g., -n 1000) or double dash (e.g., --nsamps 1000). Thank you for any advice!
To modify the moduletest.sh script to accept optional keywords that allow the user to overwrite the default values that are hard-coded in the script file. My approach was to use the getopts builtin command to parse the command line arguments.