I (presumably everyone) hit by this problem time to time but couldn't find any good workaround by myself. When getopts
looks for an argument, it literally takes the next one, even if it's an option. This is what I did to stop that (code snippet):
#!/bin/bash
function optsGet()
{
while getopts ":c:f" opt; do
case $opt in
c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]] \
&& { echo -e "ERROR: Invalid argument\n"; exit 1; }
CNAME="${OPTARG}.tEsTsTr"
;;
f ) FORCE=true
;;
\?) echo -e "Invalid option: -$OPTARG\n" >&2;;
: ) echo -e "Missing argument for -$OPTARG\n" >&2; exit 1;;
* ) echo -e "Unimplemented option: -$OPTARG\n" >&2; exit 1;;
esac
done
shift $(($OPTIND - 1))
}
optsGet "${@}"
echo -e "CNAME: ${CNAME}\n"
but it is still taking blank/null as a valid argument. So, this works:
san@AM0150 testtools$ ./getopts.sh -c -f
ERROR: Invalid argument
But these aren't:
san@AM0150 testtools$ ./getopts.sh -c " " -f
CNAME: .tEsTsTr
san@AM0150 testtools$ ./getopts.sh -c \ -f
CNAME: .tEsTsTr
I was rather expecting Missing argument for -c
error. Is there anything I'm missing here? Or does anyone know workaround? Any input will be highly appreciate. Cheers!!
Update (mainly based on devnull's reply):
Just for the completeness, now I have this little function:
function ifEmpty()
{
local VAL=$1
local OPT=$2
[[ -z "${VAL}" || "${VAL}" =~ ^[[:space:]]*$ || "${VAL}" == -* ]] \
&& { echo -e "\n ERROR: Missing argument for option: -${OPT}\n" >&2; exit 1; }
}
then this can be used like this:
c ) ifEmpty "${OPTARG}" "${opt}"
CNAME=${OPTARG//[[:space:]]}
;;
for all the options that needs an argument. Cheers!!
PS. for some reason, *[[:space:]]*
doesn't work when used in the function.
-z
would return true for an empty string, not for a string containing spaces.Check if the string consists only of whitespaces. Say:
instead of
This would also handle the null (
\
) case.EDIT:
In fact, it can also be written as: