我(大概每个人)都会遇到这个问题,但我自己找不到任何好的解决方法。当getopts
查找一个参数时,它实际上会获取下一个参数,即使它是一个选项。这就是我所做的阻止(代码片段):
#!/bin/bash
function optsGet()
{
while getopts ":c:f" opt; do
case $opt in
c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]]
&& { echo -e "ERROR: Invalid argumentn"; exit 1; }
CNAME="${OPTARG}.tEsTsTr"
;;
f ) FORCE=true
;;
?) echo -e "Invalid option: -$OPTARGn" >&2;;
: ) echo -e "Missing argument for -$OPTARGn" >&2; exit 1;;
* ) echo -e "Unimplemented option: -$OPTARGn" >&2; exit 1;;
esac
done
shift $(($OPTIND - 1))
}
optsGet "${@}"
echo -e "CNAME: ${CNAME}n"
但它仍然将blank/null作为有效的参数。所以,这是有效的:
san@AM0150 testtools$ ./getopts.sh -c -f
ERROR: Invalid argument
但这些不是:
san@AM0150 testtools$ ./getopts.sh -c " " -f
CNAME: .tEsTsTr
san@AM0150 testtools$ ./getopts.sh -c -f
CNAME: .tEsTsTr
我很期待Missing argument for -c
错误。这里有我遗漏的东西吗?或者有人知道变通办法吗?如有任何意见,我们将不胜感激。干杯
更新(主要基于devnull的回复):
为了完整起见,现在我有了一个小函数:
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; }
}
那么这个可以这样使用:
c ) ifEmpty "${OPTARG}" "${opt}"
CNAME=${OPTARG//[[:space:]]}
;;
所有需要论证的选项。干杯
PS。由于某些原因,*[[:space:]]*
在函数中使用时不起作用。
-z
将为空字符串返回true,而不是为包含空格的字符串返回true。
检查字符串是否仅由空格组成。说:
c ) [[ -z "${OPTARG}" || "${OPTARG}" =~ ^[[:space:]]*$ || "${OPTARG}" == -* ]]
而不是
c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]]
这也将处理null()情况。
EDIT:
实际上,它也可以写成:
c ) [[ -z "${OPTARG}" || "${OPTARG}" == *[[:space:]]* || "${OPTARG}" == -* ]]
这可能是一个不回答的答案,但我不会试图阻止它。如果-c
以文件名为参数,比如说,-f
可能是有效的文件名,
(空格)也是如此。一般来说,我不认为shell脚本应该做一些"有用"的事情,比如修剪空白或抛出不寻常但技术上有效的参数。