사용되지 않은 getopts 인수 처리(옵션이 필수가 아닌가요?)

사용되지 않은 getopts 인수 처리(옵션이 필수가 아닌가요?)

getopts로 시작하고 다음과 같은 스크립트가 있습니다.

USAGE() { echo -e "Usage: bash $0 [-w <in-dir>] [-o <out-dir>] [-c <template1>] [-t <template2>] \n" 1>&2; exit 1; }

if (($# == 0))
then
    USAGE
fi

while getopts ":w:o:c:t:h" opt
do
    case $opt in
        w ) BIGWIGS=$OPTARG
        ;;
        o ) OUTDIR=$OPTARG
        ;;
        c ) CONTAINER=$OPTARG
        ;;
        t ) TRACK=$OPTARG
        ;;
        h ) USAGE
        ;;
        \? ) echo "Invalid option: -$OPTARG exiting" >&2
       exit
        ;;
        : ) echo "Option -$OPTARG requires an argument" >&2
        exit
        ;;
    esac
done

more commands etc

echo $OUTDIR
echo $CONTAINER

나는 이 스크립트에 대해 몇 가지 테스트를 하고 있는데 어떤 단계에서는 -c 매개변수 [-c]를 사용할 필요가 없거나 사용하고 싶지 않습니다. 즉, $CONTAINER 변수를 전혀 포함하지 않는 스크립트의 또 다른 특정 부분을 테스트하려고 합니다. 그래서 $CONTAINER의 모든 명령 앞에 #을 추가하고 몇 가지 테스트를 해보니 잘 작동했습니다.

$CONTAINER를 사용하지 않고 스크립트를 테스트할 때 다음을 입력합니다.

bash script.bash -w mydir -o myoutdir -t mywantedtemplate

그러나 getopts 명령이 주어졌을 때 경고가 표시되지 않는지 궁금합니다. 즉, -c 매개변수가 필요하다는 경고가 표시되지 않는 이유는 무엇입니까? 가능합니까? 다음을 입력할 때만 경고가 나타납니다.

bash script.bash -w mydir -o myoutdir -t mywantedtemplate -c

고쳐 쓰다

몇 가지 테스트를 거친 후 다음과 같은 생각이 들었습니다.

  • 명시적으로 "-c"를 쓰지 않으면 getopts는 "질문"하지 않고 오류를 표시합니다(스크립트가 이를 사용하여 뭔가를 수행하지 않는 한 - 즉, 각 명령 앞에 #을 넣지 않은 경우). 이 주장)
  • "-c"만 입력하고 아무 것도 입력하지 않으면 오류가 발생합니다.

맞습니까? 아마도 내가 한 일은 "나쁜 습관"이었으므로 피해야 합니다. 테스트할 때 getopts 명령에서 c:를 완전히 제거했어야 했습니다.

내가 묻는 것은 다음과 같습니다. getopts에 매개변수(내 스크립트의 "while" 줄)에 대해 알려줄 때 우리는 다음과 같이 말합니다. 이것은 예상할 수 있는 옵션이며 ":" 뒤에 오는 옵션에는 매개변수가 있어야 합니다. 그들을 . 그러나 그것들은 주어질 필요가 없습니다. 즉, 인수가 포함된 c 옵션을 기대할 수 있지만 c 옵션이 전혀 제공되지 않아도 오류가 발생하지 않습니다.

답변1

유틸리티 getopts는 모른다필수적인옵션, 어떤 옵션이 허용되는지(그리고 어떤 옵션이 옵션 인수를 취해야 하는지)에 대해서만 설명합니다. 필수 옵션을 적용하려면 옵션 구문 분석 루프 내부 또는 이후에 자체 테스트를 수행해야 합니다.

getopts일부 옵션이 충돌하거나 일부 옵션에 다른 옵션이 있어야 하는 등 옵션이 더 복잡한 관계를 가질 수 있기 때문에 유틸리티는 이 작업을 수행하지 않습니다 . 이는 스크립트 작성자가 자신의 논리에 따라 정리하도록 남겨 둡니다.

답변2

당신이 무엇을 요구하는지 잘 모르겠지만, 그것이 하는 일은 getopts프로그램에 제공된 명령줄을 구문 분석하고 창에 표시되는 옵션을 하나씩 팝업하는 것입니다. 프로그램 코드는 처리하기 쉬운 형식으로 되어 있습니다. 알지 못하는 옵션에 대한 오류를 인쇄하는 옵션이 있지만 그게 전부입니다.

getopts호출 시 명령줄이 이미 수정되어 있기 때문에 실제로 아무에게도 "요청"하지 않습니다. 프로그램의 나머지 부분이 이를 구현하지 않는 한 상호 작용은 없습니다.

또한 프로그램을 실행하는 데 어떤 옵션이 필요한지 알지도 못합니다( getopts매개변수인 "optstring"에는 해당 구문이 없습니다). 평소 상황은아니요옵션은 필수입니다(예 ls: , rm, vi...). 필수 옵션이 있는 경우 스크립트에서 수동으로 확인할 수 있습니다.

다음 예를 고려하십시오.

#!/bin/bash

opt_a=
opt_b=
while getopts 'a:bc' opt; do
    case $opt in
        a) opt_a=$OPTARG;;
        b) opt_b=1;;
    esac
done

if [ -z "$opt_a" ]; then
    echo "option a was NOT given, exit."
    exit 1;
fi
echo "do something with a='$opt_a' b=$opt_b"

스크립트는 a그것이 제공되었는지 명시적으로 확인합니다. 확인하지 않으면 프로그램이 계속 실행됩니다. 또한 옵션으로 getopts수락하라는 메시지가 표시 되며 오류가 발생하지 않습니다. 케이스나 케이스를 c넣지 않았기 때문에 스크립트는 이를 완전히 무시했습니다 . 이 특정 옵션이 무시되는지 알 수 있는 방법이 없습니다 .c)*)getopts

프롬프트에서 대괄호를 사용하는 일반적인 의미는 해당 옵션이 선택 사항임을 알리는 것이므로 모든 -w, -o, -c, 을 -t스크립트에 제공해야 한다는 의미라면 대괄호를 제거하는 것이 좋습니다.

관련 정보