我有三个变量,我们将它们称为DATE
,URI
和URI_FILE
。它们包含使用getopt
处理命令行的结果:
while getopts ":d:p:u:hFA" opt; do
case $opt in
d) DATE=$OPTARG;;
u) URI=${OPTARG};;
U) URI_FILE=${OPTARG};;
F) FORCE=yes;;
A) ALL=yes;;
esac
done
如果将多个变量中的一个以上设置为任意值(它们是备用命令行选项),我将失败并出错。我对如何进行优雅测试一无所知。我有类似的东西:
#!/bin/bash
if [[ -z "${URI+x}" ]]
then
URI_PRESENT=0
else
URI_PRESENT=1
fi
if [[ -z "${URI_FILE+x}" ]]
then
URI_FILE_PRESENT=0
else
URI_FILE_PRESENT=1
fi
if [[ -z "${DATE+x}" ]]
then
DATE_PRESENT=0
else
DATE_PRESENT=1
fi
ARGCOUNT=$((${DATE_PRESENT} + ${URI_FILE_PRESENT} + ${URI_PRESENT}))
if (( ${ARGCOUNT} > 1 ))
then
echo "Only one of date, uri and uri-file may be supplied"
exit 1
fi
必须有一种更清洁的方法来执行此操作。有什么建议吗?我将至少添加更多替代方案,这会很痛苦
答案 0 :(得分:3)
counter=0
[[ $DATE ]] && ((counter+=1))
[[ $URI ]] && ((counter+=1))
[[ $URI_FILE ]] && ((counter+=1))
if ((counter > 1))
then
echo "Only one of date, uri and uri-file may be supplied" >&2
exit 1
fi
答案 1 :(得分:3)
为什么没有一个标志会在每个
case
表达式中递增,然后测试它是否大于1?
已实施:
while getopts ":d:p:u:hFA" opt; do
case $opt in
d) DATE=$OPTARG
((count++));;
u) URI=${OPTARG}
((count++));;
U) URI_FILE=${OPTARG}
((count++));;
F) FORCE=yes;;
A) ALL=yes;;
esac
if ((count > 1)); then
echo "Only one of date, uri or uri-file may be supplied" >&2
exit 1
fi
done
答案 2 :(得分:2)
创建一个由选项列表中每个互斥选项索引的关联数组,然后报告其大小是否大于1:
#!/bin/env bash
declare -A opts
while getopts ":d:u:U:hFA" opt; do
case $opt in
d) DATE=$OPTARG
opts["$opt"]=1;;
u) URI=${OPTARG}
opts["$opt"]=1;;
U) URI_FILE=${OPTARG}
opts["$opt"]=1;;
F) FORCE=yes;;
A) ALL=yes;;
esac
if (( ${#opts[@]} > 1 )); then
echo "Only one of date, uri or uri-file may be supplied" >&2
exit 1
fi
done
这将允许在命令行上存在同一选项的多个实例,而不允许有2个或更多不同选项的实例。