bash 中的 getopts,脚本之前运行正常,现在我感到困惑
getopts in bash, script was working before and now I'm baffled
所以我的 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
稍后检查 count=1 的 case 语句(意思是,在调用中仅使用以下 i、p 和 s 之一)不重要,除了它确定主要操作是完成。
现在有问题的是 getopts。这以前是有效的,现在不是了。目标是让如果有人想输入数据,他们可以使用以下 bash 命令。
./programname -i -f Mary -l Sue -e smary@email.com -n 555-555-5555
其中,当使用 -i 时,我们必须有 -f、-l、-e 和 -n(用于名字、姓氏、电子邮件和电话号码)。
我使用的代码:警告,代码中充满了语法错误。如果您正在学习 bash,我强烈建议您不要使用您在我的 post.
中看到的任何内容
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 做错了什么?之前还可以,现在……完全不行了!
有一件事值得注意:如果您的脚本已经调用了一次 getopts
,另一个 getopts
调用将在所有选项之后开始,因此实际上什么都不做;在每个后续 getopts
调用之前将 OPTIND
重置为 1
以让他们重新处理所有选项。
您的代码有两个语法错误,总体上值得清理:
if [[ -z ...
语句缺少 then
。
usage
之后的 //
会导致语法错误 - POSIX-like shells 使用 #
作为注释字符。
- 因为这是
bash
脚本,坚持使用 [[ ... ]]
一贯的(不需要 [ ... ]
) and/or 使用 (( ... ))
进行算术运算。
- 具体来说,避免使用
[ ... == ... ]
,因为它混合了 POSIX 语法 - [ ... ]
- 与 Bash 特定的语法 - ==
( POSIX 只支持 =
).
- 如果您确实使用
[ ... ]
,请务必将变量引用用双引号引起来,以确保安全。
- 无需多个
[[ ... ]]
表达式将它们组合在一起 - 在 单个 [[ ... || ... || ... ]]
. 中执行
- 最好避免全大写的 shell 变量名,以便 avoid conflicts with environment variables and special shell variables.
- 使用
>&2
. 将错误消息输出到 stderr
- 用双引号将 整个 参数括在
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
所以我的 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
稍后检查 count=1 的 case 语句(意思是,在调用中仅使用以下 i、p 和 s 之一)不重要,除了它确定主要操作是完成。
现在有问题的是 getopts。这以前是有效的,现在不是了。目标是让如果有人想输入数据,他们可以使用以下 bash 命令。
./programname -i -f Mary -l Sue -e smary@email.com -n 555-555-5555
其中,当使用 -i 时,我们必须有 -f、-l、-e 和 -n(用于名字、姓氏、电子邮件和电话号码)。 我使用的代码:警告,代码中充满了语法错误。如果您正在学习 bash,我强烈建议您不要使用您在我的 post.
中看到的任何内容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 做错了什么?之前还可以,现在……完全不行了!
有一件事值得注意:如果您的脚本已经调用了一次 getopts
,另一个 getopts
调用将在所有选项之后开始,因此实际上什么都不做;在每个后续 getopts
调用之前将 OPTIND
重置为 1
以让他们重新处理所有选项。
您的代码有两个语法错误,总体上值得清理:
if [[ -z ...
语句缺少then
。usage
之后的//
会导致语法错误 - POSIX-like shells 使用#
作为注释字符。- 因为这是
bash
脚本,坚持使用[[ ... ]]
一贯的(不需要[ ... ]
) and/or 使用(( ... ))
进行算术运算。- 具体来说,避免使用
[ ... == ... ]
,因为它混合了 POSIX 语法 -[ ... ]
- 与 Bash 特定的语法 -==
( POSIX 只支持=
). - 如果您确实使用
[ ... ]
,请务必将变量引用用双引号引起来,以确保安全。
- 具体来说,避免使用
- 无需多个
[[ ... ]]
表达式将它们组合在一起 - 在 单个[[ ... || ... || ... ]]
. 中执行
- 最好避免全大写的 shell 变量名,以便 avoid conflicts with environment variables and special shell variables.
- 使用
>&2
. 将错误消息输出到 stderr
- 用双引号将 整个 参数括在
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