如何在没有参数的情况下处理 switch?

如何在没有参数的情况下处理 switch?

我为一些 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

您的代码有两处更改:

  1. 将“optstring”从 更改为:rt:告诉:rtgetopts “t”选项不需要跟随参数。
  2. 将线路更改TIMEOFDAY=${OPTARG}TIMEOFDAY=${!OPTIND}.

再次从手册页:

每次调用时,getopts 实用程序都应将下一个选项的值放置在由名称操作数指定的 shell 变量中以及要在 shell 变量 OPTIND 中处理的下一个参数的索引中。

因此,当处理“t”选项时,OPTIND变量将具有该选项的索引号。下一个选项。语法 ${!多变的} 间接引用的值多变的

我在沙箱中重新创建了它,并添加了另一行来回显 OPTIND 的值,以帮助在此处进行解释:在线尝试一下!

相关内容