我探索这个问题的时间超出了我应有的时间,并发现 getopts 是一个非常令人困惑的工具。
我想做的就是以下内容。有一个脚本,我可以传递像这样的参数 $1 $2 $3 并且其中一个是可选的 -e 电子邮件
这就是我所做的,这当然根本不起作用:
#!/bin/bash
if [[ $# -lt 2 ]] || [[ $# -gt 3 ]]
then
echo
echo "usage is `basename $0` argument1 argument2 {-e email}"
exit 1
fi
while getopts e: flag; do
case $flag in
e)
EMAIL=$OPTARG;
;;
?)
exit;
;;
esac
done
[[ -v $EMAIL ]] && echo "I am sending you $1 and $2!!" | mutt -s "present" $EMAIL && exit 0
echo "I am keeping $1 and $2 to myself"
当然我可以忽略这个 getopts 业务并且不使用它,我只是想学习如何正确使用它
答案1
您有多个问题:
- 您正在处理选项之前测试参数的数量。在处理选项之前,您不知道 argv 中的多少个插槽被选项占用,因此您无法决定是否
$#
需要在 2 到 3 之间(如您建议的那样)或其他值。即使您预测某个-e
选项的存在,您也不知道它是-eemail
(消耗 1 个 argv 插槽)还是-e email
(消耗 2 个插槽)。听起来你想接收正好 2 个非选项参数,所以你需要做的是检查它$#
是否正好等于 2后选项已被消耗。 [[ -v $EMAIL ]]
电子邮件没有任何意义。这测试是否价值of$EMAIL
指定一个有效的 shell 变量,这不是您想要的。你的意思是这样的[ -n "$EMAIL" ]
getopts
不使用选项,它只解析它们。解析完它们后,您应该使用 跳过它们shift $(($OPTIND-1))
。- 您错误地调用了脚本。选项位于参数之前,因此用法为
$0 [-e email] argument1 argument2
。