쉘 스크립트에서 스위치를 어떻게 처리합니까?

-x--xxxx를 인수가 아닌 스위치로 사용하거나 모든 입력 변수를 살펴보고 대시를 테스트 한 다음 그 후에 인수를 구문 분석해야합니까?

Answer

getopts 를 사용합니다.

POSIX 사양 그대로 이식 가능합니다. 안타깝게도 긴 옵션은 지원하지 않습니다.

getopts 튜토리얼 도 참조하세요. bash-hackers 위키와 stackoverflow의이 질문

짧은 옵션 만 필요한 경우 (무음 오류보고 사용) :

# process arguments "$1", "$2", ... (i.e. "$@") while getopts "ab:" opt; do case $opt in a) aflag=true ;; # Handle -a b) barg=$OPTARG ;; # Handle -b argument \?) ;; # Handle error: unknown option or missing required argument. esac done 

댓글

  • getopt는 사용하기 전에 항상 GNU getopt로 확인해야하지만, ' 어쨌든 사용해서는 안됩니다. 어쨌든 getopts는 이식성이 더 높고 일반적으로 더 좋습니다. 어떤 이유로 든 호출해야하는 경우 만약 GNU 특정 방식으로 호출하십시오. GETOPT_COMPATIBLE가 환경에 없는지 확인합니다.
  • while getopts "ab:" opt의 콜론은 무엇을합니까?
  • @ user394 옵션 문자 뒤의 :는이를 나타냅니다. 인수가 필요합니다. 첫 번째 문자 인 :는 오류 메시지를 표시하지 않음을 의미합니다.

답변

“bash 등을 사용하고 있다고 가정합니다. 예 :

all=false long=false while getopts ":hal" option; do case $option in h) echo "usage: $0 [-h] [-a] [-l] file ..."; exit ;; a) all=true ;; l) long=true ;; ?) echo "error: option -$OPTARG is not implemented"; exit ;; esac done # remove the options from the positional parameters shift $(( OPTIND - 1 )) ls_opts=() $all && ls_opts+=( -a ) $long && ls_opts+=( -l ) # now, do it ls "${ls_opts[@]}" "$@" 

댓글

  • +1 배열과 함께 +=을 사용합니다. ' 당신이 그렇게 할 수 있다는 것을 몰랐습니다. 좋습니다!

Answer

매개 변수를 구문 분석하려면주기를 작성해야합니다. 실제로 getopts 명령으로 쉽게 수행 할 수 있습니다.

다음은 getopts 매뉴얼 페이지의 간단한 예입니다.

aflag= bflag= while getopts ab: name do case $name in a) aflag=1;; b) bflag=1 bval="$OPTARG";; ?) printf "Usage: %s: [-a] [-b value] args\n" $0 exit 2;; esac done if [ ! -z "$aflag" ]; then printf "Option -a specified\n" fi if [ ! -z "$bflag" ]; then printf "Option -b "%s" specified\n" "$bval" fi shift $(($OPTIND - 1)) printf "Remaining arguments are: %s\n" "$*" 

Answer

최근 다재다능하고 순서에 관계없이 여러 종류의 스위치를 허용하는 작업을위한 스크립트를 작성했습니다. 명백한 법적 이유 때문에 전체 대본을 공개하십시오 (당시에는 “내가 가지고 있지 않다는 것은 말할 것도 없습니다). 그러나 여기에 그것의 고기가 있습니다. n 서브 루틴을 사용하여 스크립트 끝에서 호출합니다.

options () { if [ -n "$1" ]; then # test if any arguments passed - $1 will always exist while (( "$#" )); do # process ALL arguments if [ "$1" = ^-t$ ]; then # -t short for "test" # do something here THEN shift the argument # shift removes it from $@ and reduces $# by # one if you supply no argument shift # we can also process multiple arguments at once elif [[ "$1" =~ ^--test=[:alnum:]{1,8}$ ]] && [[ "$2" =~ ^-t2$ ]] && [[ -n "$3" ]]; then # check for 3 arguments # do something more then remove them ALL from the arg list shift 3 else echo "No matching arguments!" echo "Usage: [script options list here]" fi done else echo "Usage: [script options list here]" exit 0 fi } options "$@" # run options and loop through/process ALL arguments 

bash 스크립트를 400 줄 / 15k 자 미만으로 제한하는 것이 좋습니다. 앞서 언급 한 스크립트가이 크기를 넘어서서 작업하기가 매우 어려워졌습니다. 작업에 훨씬 더 적합한 Perl로 다시 작성하기 시작했습니다. bash에서 스크립트 작업을 할 때 염두에 두십시오. Bash는 작은 스크립트와 oneliner에 적합하지만 더 복잡한 것은 Perl로 작성하는 것이 좋습니다.

참고, 위의 내용을 테스트하지 않았으므로 작동하지 않을 수도 있지만 일반적인 아이디어를 얻을 수 있습니다.

댓글

  • 마지막에 options를 호출하는 방식 정확하지 않으면 -bash: syntax error near unexpected token $@를 반환합니다. options "$@"라고 부르세요.
  • 예, Perl과 Bash. 수정 됨.
  • while 조건이 (($#))가 아니어야합니까?
  • 이유 $#에 두 세트의 괄호가 필요합니까? 편집 : 당신이 ' 맞습니다. while (( "$#" ))

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다