How to stop getopts from being empty or null or other options as parameter value

I (presumably everyone), struck by this problem from time to time, but could not find a suitable workaround. When getopts looks for an argument, it literally takes the next one, even if it is an option. This is what I did to stop this (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 still accepts empty / null as a valid argument. So this works:

 san@AM0150 testtools$ ./getopts.sh -c -f ERROR: Invalid argument 

But this is not so:

 san@AM0150 testtools$ ./getopts.sh -c " " -f CNAME: .tEsTsTr san@AM0150 testtools$ ./getopts.sh -c \ -f CNAME: .tEsTsTr 

I rather expected the error Missing argument for -c . Is something missing here? Or does anyone know a workaround? Any input will be very valuable. Hooray!!


Update (mainly based on devnull response):

Just for 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 it can be used as follows:

 c ) ifEmpty "${OPTARG}" "${opt}" CNAME=${OPTARG//[[:space:]]} ;; 

for all parameters that require an argument. Hooray!!

PS. for some reason *[[:space:]]* does not work when used in a function.

+4
source share
2 answers

-z will return true for an empty string, not for a string containing spaces.

Check if the string contains only spaces. Say:

  c ) [[ -z "${OPTARG}" || "${OPTARG}" =~ ^[[:space:]]*$ || "${OPTARG}" == -* ]] \ 

instead

  c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]] \ 

This will also handle the null ( \ ) case.

EDIT: Actually, it can also be written as:

  c ) [[ -z "${OPTARG}" || "${OPTARG}" == *[[:space:]]* || "${OPTARG}" == -* ]] \ 
+4
source

This may be an unanswered answer, but I would not stop it. If -c takes a file name as an argument, say -f may be a valid file name, and also   (space). As a rule, I don’t think shell scripts should do β€œuseful” things, like trimming spaces or generating unusual, but technically sound arguments.

-one
source

Source: https://habr.com/ru/post/1499599/


All Articles