0

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.

jetesdal
  • 108
  • 7
  • 2
    To summarize, `getopts` doesn't really support long options so if you want them you'll have to do your own options parsing. – tjm3772 Jan 09 '23 at 14:51

0 Answers0