getopts와 함께 전달 된 옵션이 없음을 어떻게 감지합니까?


19

이 코드가 있습니다-

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
done
print 'hi'$name

bash getoptDemos.sh옵션없이 실행 hi하면 함수를 호출하는 대신 인쇄 합니다 usage. w, h 및 l 이외의 옵션이 제공되면 사용법을 호출합니다. 그런 다음 옵션을 지정하지 않으면 작동하지 않습니다.

내가 사용하는 시도 ?, \?, :대신 *하지만 난에 원하는 것을 얻을 수 없습니다. 나는 모두가 의미 docsgetopt말한다 그것을 사용 ?.

내가 도대체 ​​뭘 잘못하고있는 겁니까?


어떤 셸을 사용하고 있습니까?
Julian Julian

나는 그것을 아래에서 실행/bin/bash
Hussain Tamboli

답변:


15

옵션없이이 스크립트를 실행하면 getopt가 false를 리턴하므로 루프에 전혀 들어 가지 않습니다. 인쇄로 드롭 다운됩니다-이 ksh / zsh입니까?

옵션이 있어야하는 경우 루프 후 $ name을 테스트하는 것이 가장 좋습니다.

if [ -z "$name" ]
then
   usage
   exit
fi

그러나 셸을 시작할 때 환경에 있을 수 있으므로 $name호출하기 전에 비어 있는지 확인하십시오.getopts$name

unset name

( getopts루프 전에 )


아니. 배쉬. 그래서 내가 원하는 것을 어떻게 달성합니까 no argument-bash를 사용 하여 조건을 처리하십시오 .
Hussain Tamboli

필수 옵션을 원한다면 가능하지 않다고 생각합니다. 아마도 옵션이라고 불리는 이유는 다음과 같습니다. 만약 [-z "$ name"]; 그런 다음 사용법; 종료; fi
줄리안

감사. 위의 코드가 실제로 도움이되었습니다. 너무 나쁘면 getopts그러한 조항이 없습니다. 그것보다 더 나쁜 것은 당신을 공감할 수 없다는 것입니다.
Hussain Tamboli

다른 쉘을 실행하면 어떻게됩니까? zsh, sh. bash 이외의 쉘 이이 상태를 처리합니까?
Hussain Tamboli

20

getopts옵션을 차례로 처리합니다. 그게 직업입니다. 사용자가 옵션을 전달하지 않으면 첫 번째 호출은 getoptswhile 루프 를 종료합니다.

옵션을 인수로 취하지 않는 경우 값 OPTIND은 전달 된 옵션 수 를 나타냅니다. 일반적으로 OPTIND비 옵션 인수 (피연산자)와 달리 옵션 또는 옵션에 대한 인수 인 인수의 수입니다.

while getopts …; do …; done
if [ $OPTIND -eq 1 ]; then echo "No options were passed"; fi
shift $((OPTIND-1))
echo "$# non-option arguments"

어쨌든, 옵션이 없는지 여부를 결정하려는 것이 아니라 name-setting 옵션이 전달 되지 않았는지 여부 입니다. 따라서 설정이 해제되어 있는지 확인하십시오 name(먼저 설정 해제에주의하십시오) .


1
감사. 당신을 위해 +1. sample.sh에 코드의 마지막 3 줄을 넣고 실행 bash sample.sh -abc file.txt하면-가 1 non-option arguments됩니다. 얼마나 많은 옵션이 주어 졌는지 어떻게 알 수 있습니까? (여기 3)
후세인 Tamboli

1
이상한 버그에 대해서는 아무도 언급하지 않았다. 옵션이 없다면 OPTIND는 'while getopts ...'루프 다음에 1이된다. 따라서 if 검사는 0이 아닌 1과 같은지 확인해야합니다.
Daniel

4

스크립트가 옵션 인수를 받아야하는 경우이 블록을 시작 (getops 앞)에 두십시오.

if [[ ! $@ =~ ^\-.+ ]]
then
  #display_help;
fi

블록은 매개 변수 문자열이 -기호로 시작하지 않는지 점검합니다. 이는 첫 번째 매개 변수가 옵션 인수가 아님을 나타냅니다.


2

변수로 확인하겠습니다. 인수가없는 경우 getopts가 루프를 절대 통과하지 않으면 다음과 같이 사용할 수 있습니다.

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}

no_args="true"
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
    no_args="false"
done

[[ "$no_args" == "true" ]] && { usage; exit 1; }

print 'hi'$name

0

getopts블록 직전에 $1(명령 행에 전달한 첫 번째 인수 / 옵션)이 빈 문자열과 같은지 확인하십시오. 그렇다면 사용법 메시지를 인쇄하고 종료하십시오 (또는 아나키스트 인 경우 "옵션 없음"기능을 실행하십시오). 그렇지 않으면 getopts옵션을 일반처럼 구문 분석하십시오.

이 기능이 getopts에 포함되지 않은 이유는 이미 "if-else"로 bash에서이 기능을 수행 할 수 있기 때문입니다. 예:

if [[ $1 == "" ]]; then
    Your_Usage_Function;
    exit;
else
   #parse options with getopts code block here;
fi

말이 되나요?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.