Reputation: 895
I've a script where I can pass different set of arguments for the work the script has to do. The options are specified below:
[Show Help] ./myscript.sh -h
[To Create] ./myscript.sh -c -f /input_loc/input_file.txt
[To Export] ./myscript.sh -e -d /destination_loc/exported_db_date.csv
[To Import] ./myscript.sh -i -s /source_loc/to_import_date.csv
And the script myscript.sh
has getopts
to parse the options and then push it to case - esac
to apply checks and logics for each of the arguments passed to check their validity. For example, like below:
while getopts "cd:ef:his:" o; do
case "${o}" in
Put options and their check logics
esac
done
My question is, what logic can I use to force arguments to be presented in particular sets only, for e.g.
Allowed Option set
./myscript.sh -h
./myscript.sh -c -f <file_name>
./myscript.sh -e -d <file_name>
./myscript.sh -i -s <file_name>
NOT Allowed Option set
./myscript.sh -h -c -f <file_name>
./myscript.sh -h -d <file_name>
./myscript.sh -e -s <file_name>
./myscript.sh -c -i -f <file_name>
Upvotes: 2
Views: 184
Reputation: 895
I've used if...elif...else loop for this
#!/bin/bash
my_ary=("$@")
LEN=${#my_ary[@]}
if [[ ${my_ary[0]} =~ "-h" && $LEN -eq 1 ]] || \
[[ ${my_ary[0]} =~ "-c" && ${my_ary[1]} =~ "-f" && $LEN -eq 3 ]] || \
[[ ${my_ary[0]} =~ "-e" && ${my_ary[1]} =~ "-d" && $LEN -eq 3 ]] || \
[[ ${my_ary[0]} =~ "-i" && ${my_ary[1]} =~ "-s" && $LEN -eq 3 ]]; then
echo "Proper set of arguments passed"
else
echo "You are not passing arguments in proper sets, please look at Usage once again..."
fi
Is there a better way to do the same checks?
Upvotes: 1
Reputation: 85590
I think your specific usage of getopts()
here is needed only to parse the valid option flags first and put them into an array and use the parsed flags later for ensuring only if the required order of flags are set.
The steps involved are two-fold. Firstly parse the valid flags to an array (multi
) and secondly join the flags together without spaces and do a regex match on the provided flags, if you encounter ones that aren't allowed don't do your logic.
#!/usr/bin/env bash
while getopts "cd:ef:his:" opt; do
case "$opt" in
c|d|e|f|h|i|s) multi+=("$opt");;
*) printf 'invalid flag provided' 1>&2 ; exit 1 ;;
esac
done
joined=$(IFS=;echo "${multi[*]}")
if ! [[ $joined =~ ^(hcf|hd|es|cif)$ ]]; then
printf 'valid flags provided\n'
# Add your logic here
fi
Note, the answer does consider the option of swapping your flags order, i.e. if ./myscript.sh -h -c -f <file_name>
isn't allowed, should ./myscript.sh -f <file_name> -h -c
be allowed? Need to modify the answer based on that.
Upvotes: 1