I'm trying to create a shell script that has two mandatory arguments (arg1, arg2) and then an optional -b flag plus the argument that needs to follow should the user choose to use the flag.
Let me explain:
It's an install script that takes an advantage of GIT to fetch an application from a Github repository. The user types in terminal f.ex.:
./shellscript.sh new <app_name> # fetches master branch by default
and the script fetches an instance of the master branch from this repository. Should the user however choose to use the optional -b flag that would mean that he/she wants to specify which branch to fetch, e.g. develop branch. Meaning that the user could do:
./shellscript.sh new <app_name> -b develop # or which ever branch there is available
I'm also curious how you could go about making the script work so that it wouldn't matter if the user types in the -b flag+branch_name before the 'new' argument and the 'app_name' argument. But that is perhaps not the most important thing at the moment.
To know what exactly I'm trying to build, here is a link to my current script that only takes the two mandatory arguments and only fetches the master branch: My Super Cool Artisan Executable Script
P.S.: I've been trying out many examples using getopts which I've found both here on Stackoverflow and other blogs out there but none have helped me to completely make it work. Thus am I here asking y'all great people for help.
Huge thanks and be sure to check out my Linux Mint / Ubuntu - Post Install Script for only cool people(you guys and those switching over to Linux from Windows/Mac)
Regards, Villi
I normally write my own to allow for short and long options:
function Usage()
{
cat <<-ENDOFMESSAGE
$0 [OPTION] REQ1 REQ2
options:
-b -branch branch to use
-h --help display this message
ENDOFMESSAGE
exit 1
}
function Die()
{
echo "$*"
exit 1
}
function GetOpts() {
branch=""
argv=()
while [ $# -gt 0 ]
do
opt=$1
shift
case ${opt} in
-b|--branch)
if [ $# -eq 0 -o "${1:0:1}" = "-" ]; then
Die "The ${opt} option requires an argument."
fi
branch="$1"
shift
;;
-h|--help)
Usage;;
*)
if [ "${opt:0:1}" = "-" ]; then
Die "${opt}: unknown option."
fi
argv+=(${opt});;
esac
done
}
GetOpts $*
echo "branch ${branch}"
echo "argv ${argv[@]}"
Unix utilities normally take optional arguments ("flags") before the positional arguments, although most GNU utilities, including the GNU implementation of the C library function getopt, shuffle command line arguments so that the optional arguments come first. However, the bash builtin getopts does not shuffle, which means that it is up to you to do so if you want to.
getopts always starts with the argument whose number is the value of the variable OPTIND. (OPTIND is set to 1 every time a bash function is executed, and it's a global variable. So a bit of caution is needed with bash functions which call each other.) If you want to, you can set OPTIND yourself, and the next call to getopts will start with that index. Alternatively, you can use shift to shift all the command line arguments over.
So, for example, you could do this:
# "shift" version: always shift consumed arguments
local verb="$1" branch=master app_name option
shift
case $verb in
new) app_name="$1"
shift
while getopts b: option; do
case $option in
b) branch=$OPTARG;;
*) # handle the error;;
esac
done
shift $((OPTIND - 1));;
*) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > 0))
Or:
# non-shift version: use OPTIND to index arguments
local verb="${!OPTIND}" branch=master app_name option
OPTIND=$((OPTIND + 1))
case $verb in
new) app_name="${!OPTIND}"
OPTIND=$((OPTIND + 1))
while getopts b: option; do
case $option in
b) branch=$OPTARG;;
*) # handle the error;;
esac
done;;
*) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > $#))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With