bash 명령 줄에 getopt
명령이 있습니다. getopt
는 짧은 옵션 (예 : getopt -o axby "$@"
)과 함께 사용할 수 있으며 짧은 옵션과 긴 옵션 (예 : getopt -o axby -l long-key -- "$@"
), 그러나 이제는 긴 옵션 만 만 필요합니다 (즉, 짧은 옵션은 전혀 존재하지 않음). 그러나 명령은 getopt -l long-key -- "$@"
가 --long-key
옵션을 올바르게 구문 분석하지 않습니다. 그렇다면 긴 옵션 만 과 함께 getopt
명령을 어떻게 사용할 수 있습니까? 아니면 불가능하거나 단지 getopt
명령의 버그입니까?
댓글
답변
getopt
는 짧은 옵션이 없어도 완벽합니다. 그러나 당신은 짧은 선택권이 없다고 말할 필요가 있습니다. 설명서의 구문에서 “특이합니다.
-o
또는--options
옵션은 첫 번째 부분에 있으며 두 번째 부분의 첫 번째 매개 변수는 짧은 옵션 문자열로 사용됩니다.
이것이 바로 테스트에서 일어나는 일입니다. getopt -l long-key -- --long-key foo
는 --long-key
를 옵션 목록으로 취급합니다. -egklnoy
및 foo
를 유일한 인수로 사용합니다.
getopt -o "" -l long-key -- "$@"
예
$ getopt -l long-key -o "" -- --long-key foo --long-key -- "foo" $ getopt -l long-key -o "" -- --long-key --not-recognized -n foo getopt: unrecognized option "--not-recognized" getopt: invalid option -- "n" --long-key -- "foo"
댓글
- OP '가 및
getopt
가 답변에 감염 되었습니까?getopts
주석으로 시작한 다음 . - @Anthon 모든 대답은 GNU coreutils의
getopt
프로그램에 대한 것입니다. Igetopts
라는 텍스트를 수정했습니다. 감사.getopts
는 ' 긴 옵션도 수행하지 않으므로getopts
에는 적용되지 않습니다. . - OP에는 원래
getopts
태그가있었습니다. 나는 당신의 대답을 바꾸고 싶지 않았습니다. 당신은 당신이 쓰는 것에 대해 저보다 일반적으로 훨씬 더 잘 알고 있기 때문입니다. 🙂 - 나는 이것을 알아 내려고 거의 한 시간을 잃었습니다. 헛된 커피 모금 몇 모금을 구해 주셨습니다. 감사합니다 … 이제이 커피를 더 잘 사용하도록하겠습니다. ☕️
답변
Dunno about getopt
그러나 getopts
내장 기능은 다음과 같은 긴 옵션 만 처리하는 데 사용할 수 있습니다.
while getopts :-: o do case "$o$OPTARG" in (-longopt1) process ;; (-longopt2) process ;; esac; done
물론있는 그대로입니다. ” 긴 옵션이 논쟁을해야하는 경우에는 작동합니다. 그래도 할 수 있지만, 제가이 작업에 대해 배웠 듯이. 처음에 여기에 포함 시켰지만 긴 옵션의 경우별로 유용하지 않다는 것을 깨달았습니다.이 경우에는 case
(match)
필드를 예측 가능한 단일 문자로 표시합니다. 이제 제가 아는 것은 짧은 옵션에 탁월하다는 것입니다. 길이를 알 수없는 문자열을 반복하고 옵션 문자열에 따라 단일 바이트를 선택할 때 가장 유용합니다. .하지만 옵션이 인자 인 경우 for var do case $var in
조합으로 할 수있는 작업이 많지 않습니다. 더 좋습니다. 단순하게 유지하기 위해.
getopt
도 마찬가지라고 생각하지만 확실하게 말할 수있을만큼 충분히 알지 못합니다. 다음과 같은 arg 배열이 주어지면 나는 내 자신의 작은 arg 파서를 보여줄 것이다. 이것은 주로 내가 alias
와 .
set -- this is ignored by default --lopt1 -s "some "\"" args" here --ignored and these are ignored \ --alsoignored andthis --lopt2 "and some "`more" --lopt1 and just a few more
이것이 제가 작업 할 arg 문자열입니다. 지금 :
aopts() { env - sh -s -- "$@" } <<OPTCASE 3<<\OPTSCRIPT acase() case "\$a" in $(fmt=" (%s) f=%s; aset "?$(($f)):";;\n" for a do case "$a" in (--) break;; (--*[!_[:alnum:]]*) continue;; (--*) printf "$fmt" "$a" "${a#--}";; esac;done;printf "$fmt" "--*" ignored) (*) aset "" "\$a";;esac shift "$((SHIFT$$))"; f=ignored; exec <&3 OPTCASE aset() { alias "$f=$(($f${1:-=$(($f))+}1))" [ -n "${2+?}" ] && alias "${f}_$(($f))=$2"; } for a do acase; done; alias #END OPTSCRIPT
이는 --
구분 기호로 구분 된 하나 또는 두 개의 인수 세트를 전달하는지 여부에 따라 두 가지 다른 방법 중 하나로 arg 배열을 처리합니다. 두 경우 모두 arg 배열에 대한 처리 순서에 적용됩니다.
다음과 같이 호출하는 경우 :
: $((SHIFT$$=3)); aopts --lopt1 --lopt2 -- "$@"
비즈니스는 acase()
함수를 다음과 같이 작성하는 것입니다.
acase() case "$a" in (--lopt1) f=lopt1; aset "?$(($f)):";; (--lopt2) f=lopt2; aset "?$(($f)):";; (--*) f=ignored; aset "?$(($f)):";; (*) aset "" "$a";;esac
그리고 .acase()
함수 정의의 명령 대체는 호출 셸이 여기 문서에서 함수의 입력을 빌드 할 때 평가되지만 acase()
는 물론 호출 쉘에서 호출되거나 정의되지 않았습니다. 물론 서브 쉘에서 호출되므로 명령 줄에서 원하는 옵션을 동적으로 지정할 수 있습니다.
구분되지 않은 배열은 문자열 --
로 시작하는 모든 인수에 대한 일치 항목으로 acase()
를 채 웁니다.
함수 서브 쉘에서 거의 모든 처리를 수행합니다. 각 arg의 값을 연관 이름으로 할당 된 별칭에 반복적으로 저장합니다. 완료되면 alias
로 저장된 모든 값을 인쇄합니다.이 값은 셸에 다시 입력 할 수있는 방식으로 인용 된 모든 저장된 값을 인쇄하도록 POSIX 지정됩니다. 그래서 내가 할 때 …
aopts --lopt1 --lopt2 -- "$@"
출력은 다음과 같습니다 :
...ignored... lopt1="8" lopt1_1="-s" lopt1_2="some "\"" args" lopt1_3="here" lopt1_4="and" lopt1_5="just" lopt1_6="a" lopt1_7="few" lopt1_8="more" lopt2="1" lopt2_1="and some "`more"
인수 목록을 살펴볼 때 케이스 블록과 일치하는지 확인합니다. 일치하는 항목을 찾으면 f=optname
플래그를 던집니다. 다시 한 번 유효한 옵션을 찾을 때까지 현재 플래그를 기반으로 빌드하는 배열에 각 후속 인수를 추가합니다. 동일한 옵션이 여러 번 지정되면 결과가 복합되고 대체되지 않습니다. 대소 문자가 아닌 모든 항목 또는 무시 된 옵션 다음에 오는 인수는 무시 된 배열에 할당됩니다.
출력은 쉘에 의해 자동으로 쉘 입력에 대해 쉘로부터 보호됩니다. :
eval "$(: $((SHIFT$$=3));aopts --lopt1 --lopt2 -- "$@")"
… 완벽하게 안전해야합니다. 어떤 이유로 든 안전하지 않다면 셸 관리자에게 버그 보고서를 제출해야합니다.
각 일치에 대해 두 종류의 별칭 값을 할당합니다. 첫째, 플래그를 설정합니다. 이것은 옵션이 일치하지 않는 인수 앞에 오는지 여부에 관계없이 발생합니다. 따라서 인수 목록에서 --flag
가 발생하면 flag=1
가 트리거됩니다. 이것은 복합적이지 않습니다. --flag --flag --flag
는 flag=1
만 가져옵니다. 이 값은 뒤에 올 수있는 모든 인수에 대해 증가하지만 합니다 . 인덱스 키로 사용할 수 있습니다. 위의 eval
를 수행 한 후 다음을 수행 할 수 있습니다.
printf %s\\n "$lopt1" "$lopt2"
… to get …
8 1
기타 :
for o in lopt1 lopt2 do list= i=0; echo "$o = $(($o))" while [ "$((i=$i+1))" -le "$(($o))" ] do list="$list $o $i \"\${${o}_$i}\" " done; eval "printf "%s[%02d] = %s\n" $list"; done
출력
lopt1 = 8 lopt1[01] = -s lopt1[02] = some " args lopt1[03] = here lopt1[04] = and lopt1[05] = just lopt1[06] = a lopt1[07] = few lopt1[08] = more lopt2 = 1 lopt2[01] = and some "`more
일치하지 않는 인수에 대해 위의 for ... in
필드에서 ignored 를 대체하여 다음을 얻습니다.
ignored = 10 ignored[01] = this ignored[02] = is ignored[03] = ignored ignored[04] = by ignored[05] = default ignored[06] = and ignored[07] = these ignored[08] = are ignored[09] = ignored ignored[10] = andthis
getopts
에 대한 태그이지만/usr/bin/getopt
명령을 사용하고 있습니다.