while getopts \"hd:R:\" arg; do
case $arg in
h)
echo \"usgae\"
;;
d)
dir=$OPTARG
;;
R)
if [[ $OPTARG =~ ^[0-9]+$ ]];then
Try:
while getopts "hd:R:" arg; do
case $arg in
h)
echo "usage"
;;
d)
dir=$OPTARG
;;
R)
if [[ $OPTARG =~ ^[0-9]+$ ]];then
level=$OPTARG
elif [[ $OPTARG =~ ^-. ]];then
level=1
let OPTIND=$OPTIND-1
else
level=1
fi
;;
\?)
echo "WRONG" >&2
;;
esac
done
I think the above code will work for your purposes while still using getopts. I've added the following three lines to your code when getopts encounters -R:
elif [[ $OPTARG =~ ^-. ]];then
level=1
let OPTIND=$OPTIND-1
If -R is encountered and the first argument looks like another getopts parameter, level is set to the default value of 1, and then the $OPTIND variable is reduced by one. The next time getopts goes to grab an argument, it will grab the correct argument instead of skipping it.
Here is similar example based on the code from Jan Schampera's comment at this tutorial:
#!/bin/bash
while getopts :abc: opt; do
case $opt in
a)
echo "option a"
;;
b)
echo "option b"
;;
c)
echo "option c"
if [[ $OPTARG = -* ]]; then
((OPTIND--))
continue
fi
echo "(c) argument $OPTARG"
;;
\?)
echo "WTF!"
exit 1
;;
esac
done
When you discover that OPTARG von -c is something beginning with a hyphen, then reset OPTIND and re-run getopts (continue the while loop). Oh, of course, this isn't perfect and needs some more robustness. It's just an example.