我为一些 USB 网络摄像头图像设置和重新启动网络摄像头服务编写了一个简单的 bash 脚本。
此时,当有人使用 -t 标志时,他们只能使用“n”或“d”,如果他们使用其他内容,则会抛出错误。但是,如果他们使用不带任何参数的 -t ,则会发生相同的错误。
有没有办法分别处理这两个?
另外,有没有一种方法可以以不同于我使用的方式对多个变量使用“case”语句?
我在想我可以用 VBA 做些什么:
Select Case True
Case a = 1 and b = 2
*something something*
Case a = 2 and b = 1
*something something*
End Select
谢谢
#!/bin/bash
RESTART="The camera was restarted."
RESTARTDAY="The camera was restarted and controls were set for daytime."
RESTARTNIGHT="The camera was restarted and controls were set for nighttime."
DAY="The camera controls were set for daytime."
NIGHT="The camera control were set for nighttime."
REST=false
TIME=false
unstuck_image(){
v4l2-ctl -c brightness=10
v4l2-ctl -c contrast=10
v4l2-ctl -c gamma=10
v4l2-ctl -c saturation=10
v4l2-ctl -c sharpness=10
}
set_night(){
v4l2-ctl -c gain_automatic=0
v4l2-ctl -c brightness=75
v4l2-ctl -c contrast=75
v4l2-ctl -c gamma=20
v4l2-ctl -c saturation=15
v4l2-ctl -c sharpness=90
}
set_day(){
v4l2-ctl -c gain_automatic=0
v4l2-ctl -c brightness=50
v4l2-ctl -c contrast=50
v4l2-ctl -c gamma=20
v4l2-ctl -c saturation=15
v4l2-ctl -c sharpness=90
}
restart_camera(){
sudo service webcamd restart
}
while getopts :rt: option
do
case "${option}" in
r)
REST=true
#echo "Restart"
;;
t)
TIMEOFDAY=${OPTARG}
TIME=true
case "$TIMEOFDAY" in
n | d)
#echo "$TIMEOFDAY"
;;
*)
echo "Invalid argument for -t, use only 'd' or 'n'"
exit 0
;;
esac
;;
*)
echo "Argument -${OPTARG} not found."
echo "Use only -r and -t."
exit 0
;;
esac
done
RESTTIME="$REST""$TIME"
#echo "$RESTTIME"
#echo "$RESTART"
case "$RESTTIME" in
"truefalse") #Only restart webcamd
restart_camera
MESSAGE="$RESTART"
;;
"truetrue") #Restart webcamd and set camera controls
case "$TIMEOFDAY" in
d)
restart_camera
unstuck_image
set_day
MESSAGE="$RESTARTDAY"
;;
n)
restart_camera
unstuck_image
set_night
MESSAGE="$RESTARTNIGHT"
;;
esac
;;
"falsetrue") #Only set the camera controls
case "$TIMEOFDAY" in
d)
unstuck_image
set_day
MESSAGE="$DAY"
;;
n)
unstuck_image
set_night
MESSAGE="$NIGHT"
;;
esac
;;
esac
echo "$MESSAGE"
编辑:
除了spuck的回答之外,我自己做了一些挖掘,发现它也可以这样完成:
while getopts :rt: option
do
case "${option}" in
r)
REST=true
#echo "Restart"
;;
t)
TIMEOFDAY="${OPTARG}"
TIME=true
case "${TIMEOFDAY}" in
n | d)
#echo "$TIMEOFDAY"
;;
"")
echo "-t argument requires an option. Use 'd' or 'n'."
exit 2
;;
*)
echo "Invalid argument for -t. Use only 'd' or 'n'"
exit 0
;;
esac
;;
\?)
echo "Argument -"${OPTARG}" not found. Use only -r and -t."
exit 0
;;
:)
echo "Invalid option: -"${OPTARG}" requires an argument"
exit 2
;;
esac
done
其中 :) 处理标志的参数不是可选的但缺少的情况。
答案1
你的使用getopts :rt:
会告诉 shell 你要求选项“t”的参数。
从 getopts 手册页:
[...] 如果一个字符后面跟着一个冒号,则该选项应该有一个参数,该参数应该用空格与其分隔 [...] 当一个选项需要一个参数时,getopts 将该参数放入变量OPTARG
如果你想让 -t 的参数可选,你需要删除冒号并手动处理下一个参数:
while getopts :rt option
do
case "${option}" in
r)
REST=true
#echo "Restart"
;;
t)
TIMEOFDAY=${!OPTIND}
TIME=true
case "$TIMEOFDAY" in
n | d)
echo "$TIMEOFDAY"
;;
"")
echo "-t argument requires an option."
exit 2
;;
*)
echo "Invalid argument for -t, use only 'd' or 'n'"
exit 0
;;
esac
;;
*)
echo "Argument -${OPTARG} not found."
echo "Use only -r and -t."
exit 0
;;
esac
done
您的代码有两处更改:
- 将“optstring”从 更改为
:rt:
告诉:rt
getopts “t”选项不需要跟随参数。 - 将线路更改
TIMEOFDAY=${OPTARG}
为TIMEOFDAY=${!OPTIND}
.
再次从手册页:
每次调用时,getopts 实用程序都应将下一个选项的值放置在由名称操作数指定的 shell 变量中以及要在 shell 变量 OPTIND 中处理的下一个参数的索引中。
因此,当处理“t”选项时,OPTIND变量将具有该选项的索引号。下一个选项。语法 ${!多变的} 间接引用的值多变的。
我在沙箱中重新创建了它,并添加了另一行来回显 OPTIND 的值,以帮助在此处进行解释:在线尝试一下!