所以我的bash脚本中有几个getopts。这是一个工作的例子。
FOUND=
SEARCH=
COUNT=0
while getopts "ips:flenkc" OPTION
do
case $OPTION in
i)
FOUND=1
let "COUNT++"
;;
p)
FOUND=2
let "COUNT++"
;;
s)
FOUND=3
SEARCH=$OPTARG
let "COUNT++"
;;
esac
done
稍后在一个case语句中检查count = 1(意味着,在调用中只使用以下一个,i,p和s)并不重要,除非它确定正在执行的主要操作。
现在有问题了。这在以前工作,现在不是。目标是使其如果有人想要输入数据,他们可以使用以下bash命令来执行此操作。
./programname -i -f Mary -l Sue -e smary@email.com -n 555-555-5555
当使用-i时,我们必须有-f,-l,-e和-n(对于名字,姓氏,电子邮件和号码)。 我正在使用的代码:警告,代码中充满了语法错误。如果您正在学习bash,我强烈建议您不要使用我在帖子中看到的任何内容。
if [ $FOUND == "1" ]
then
echo "You have chosen to insert things."
FIRST=
LAST=
EMAIL=
NUMBER=
while getopts "if:l:e:n:" OPTION
do
case $OPTION in
f)
FIRST=$OPTARG
;;
l)
LAST=$OPTARG
;;
e)
EMAIL=$OPTARG
;;
n)
NUMBER=$OPTARG
;;
esac
done
if [[ -z $FIRST ]] || [[ -z $LAST ]] || [[ -z $EMAIL ]] || [[ -z $NUMBER ]]
echo "Error!!! Some input is missing!!!"
usage // display usage
exit 1
fi
echo -e $FIRST"\t"$LAST"\t"$EMAIL"\t"$NUMBER >> contacts
fi
在此程序运行之前,但是现在,甚至没有一件事能让它输入FIRST,LAST,EMAIL和NUMBER(我尝试更改代码以查看它是否正在执行某些步骤)
我对getopts做错了什么?它之前工作正常,但现在......它根本不起作用!
答案 0 :(得分:5)
前面值得注意的一件事:如果您的脚本已经调用getopts
一次,则另一个getopts
调用将在所有选项之后启动,因此无效地执行任何操作;在每次后续OPTIND
调用之前将1
重置为getopts
,让他们重新处理所有选项。
您的代码既有语法错误,也值得清理:
if [[ -z ...
语句缺少then
。//
之后的usage
会导致语法错误 - 类似POSIX的shell使用#
作为注释字符。bash
脚本,因此请坚持使用[[ ... ]]
一致(不需要[ ... ]
)和/或使用(( ... ))
进行算术运算。
[ ... == ... ]
,因为它将POSIX语法 - [ ... ]
与特定于Bash的语法混合在一起 - ==
(POSIX仅支持=
)。[ ... ]
,请务必双引号变量引用,以确保安全。[[ ... ]]
表达式将它们组合在一起 - 在单 [[ ... || ... || ... ]]
中执行此操作。>&2
echo -e
中,以保护变量值免受可能不需要的扩展。通常可以使用shellcheck.net来捕获语法错误。
总而言之,我们得到:
#!/usr/bin/env bash
# ... code that sets $found
# If you've already processed args. with getopts above,
# you must reset OPTIND to process them again.
OPTIND=1
if (( found == 1 )) # found is numeric, use arithmetic expression to compare
then
echo "You have chosen to insert things."
first= last= email= number= # don't use all-uppercase var. names
while getopts "if:l:e:n:" option
do
case $option in
f)
first=$OPTARG
;;
l)
last=$OPTARG
;;
e)
email=$OPTARG
;;
n)
number=$OPTARG
;;
esac
done
if [[ -z $first || -z $last || -z $email || -z $number ]]; then
echo "Error!!! Some input is missing!!!" >&2
usage # display usage
exit 1
fi
echo -e "$first\t$last\t$email\t$number" >> contacts
fi