매개변수 없이 스위치를 처리하는 방법은 무엇입니까?

매개변수 없이 스위치를 처리하는 방법은 무엇입니까?

일부 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:쉘에 귀하가필요하다옵션 '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"을 from에서로 변경하면 "t" 옵션에는 다음 인수가 필요하지 않음을 getopts에 :rt:알립니다 .:rt
  2. 줄을 TIMEOFDAY=${OPTARG}로 변경합니다 TIMEOFDAY=${!OPTIND}.

다시 매뉴얼 페이지에서:

각 호출에서 getopts 유틸리티는 name 피연산자로 지정된 쉘 변수에 다음 옵션 값을 배치하고 쉘 변수 OPTIND에서 처리할 다음 인수의 인덱스를 배치해야 합니다.

따라서 "t" 옵션이 처리되면 OPTIND 변수는 해당 옵션의 인덱스 번호를 갖게 됩니다.다음옵션. 구문 ${!바꾸다} 간접 참조의 값바꾸다.

여기서 설명하는 데 도움이 되도록 샌드박스에서 이를 다시 생성하고 OPTIND 값을 반영하는 또 다른 줄을 추가했습니다.온라인으로 사용해 보세요!

관련 정보