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

이 코드가 있습니다-

#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말한다 그것을 사용 ?.

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



답변

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

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

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

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

unset name

( getopts루프 전에 )


답변

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(먼저 설정 해제에주의하십시오) .


답변

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

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

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


답변

변수로 확인하겠습니다. 인수가없는 경우 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


답변

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

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

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

말이 되나요?


답변