getopt
그리고 getopts
다른 짐승이 있고, 사람들은 무슨 오해의 조금을 갖고있는 것 같다. getopts
는 bash
명령 행 옵션을 루프로 처리하고 찾은 각 옵션과 값을 내장 변수에 차례로 지정하여 추가로 처리 할 수있는 내장 명령입니다. getopt
그러나 외부 유틸리티 프로그램이며 bash , Perl 모듈 또는 Python / 모듈 과 같은 옵션을 실제로 처리하지는 않습니다 . 이 모든 수행은 규범화에게 전달되는 옵션입니다 - 즉, 그것이 그들을 처리하는 쉘 스크립트 쉽게 그래서, 더 표준 형태로 변환. 예를 들어의 응용 프로그램은 다음을 변환 할 수 있습니다.getopts
Getopt
optparse
argparse
getopt
getopt
myscript -ab infile.txt -ooutfile.txt
이것으로 :
myscript -a -b -o outfile.txt infile.txt
실제 처리를 직접 수행해야합니다. getopt
옵션을 지정할 수있는 방법에 대해 다양한 제한을 설정 한 경우 전혀 사용할 필요가 없습니다 .
- 인수 당 하나의 옵션 만 넣으십시오.
- 모든 옵션은 위치 매개 변수 (즉, 옵션이 아닌 인수)보다 우선합니다.
- 값이있는 옵션 (예 :
-o
위)의 경우 값은 공백 뒤에 별도의 인수로 가야합니다.
왜 getopt
대신에 사용 getopts
합니까? 기본적인 이유는 GNU만이 getopt
긴 이름의 명령 줄 옵션을 지원하기 때문입니다 . 1 ( getopt
Linux에서는 GNU 가 기본값입니다. Mac OS X 및 FreeBSD는 기본적이고 유용 getopt
하지는 않지만 GNU 버전을 설치할 수 있습니다 (아래 참조).
예를 들어, 다음 getopt
은 내 스크립트에서 GNU를 사용하는 예입니다 javawrap
.
# NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this
# separately; see below.
TEMP=`getopt -o vdm: --long verbose,debug,memory:,debugfile:,minheap:,maxheap: \
-n 'javawrap' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
VERBOSE=false
DEBUG=false
MEMORY=
DEBUGFILE=
JAVA_MISC_OPT=
while true; do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-d | --debug ) DEBUG=true; shift ;;
-m | --memory ) MEMORY="$2"; shift 2 ;;
--debugfile ) DEBUGFILE="$2"; shift 2 ;;
--minheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MinHeapFreeRatio=$2"; shift 2 ;;
--maxheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MaxHeapFreeRatio=$2"; shift 2 ;;
-- ) shift; break ;;
* ) break ;;
esac
done
이를 통해 유사 --verbose -dm4096 --minh=20 --maxhe 40 --debugfi="/Users/John Johnson/debug.txt"
하거나 유사한 옵션을 지정할 수 있습니다 . 호출의 효과는 getopt
옵션을 --verbose -d -m 4096 --minheap 20 --maxheap 40 --debugfile "/Users/John Johnson/debug.txt"
보다 쉽게 처리 할 수 있도록 옵션을 정규화하는 것입니다. 주위에 인용 "$1"
하고 "$2"
그들에 공백이 제대로 처리 얻을과 그 인수를 보장하므로 중요하다.
처음 9 줄을 삭제하면 (모든 eval set
줄 을 통해 ) 코드가 계속 작동합니다 ! 그러나 코드는 어떤 종류의 옵션을 받아 들일지 결정하기가 훨씬 쉽습니다. 특히, 위에서 설명한 "정식"형식으로 모든 옵션을 지정해야합니다. 의 사용으로 getopt
, 그러나, 당신은 그룹의 단일 문자 옵션은 긴 옵션을 사용하여 하나의 짧은 비 모호한 형태로 사용할 수 있습니다 --file foo.txt
또는 --file=foo.txt
중 스타일, 사용 -m 4096
또는 -m4096
스타일, 임의의 순서로 옵션이 아닌 옵션을 혼합 등 getopt
인식 할 수 없거나 모호한 옵션이있는 경우 오류 메시지를 출력합니다.
참고 : 실제로 기능과 호출 규칙이 서로 다른 완전히 다른getopt
기본 버전 getopt
과 GNU 버전이 getopt
있습니다. 2 기본 getopt
은 상당히 깨졌습니다 : 긴 옵션을 처리 할뿐만 아니라 인수 또는 빈 인수 내부에 포함 된 공백도 처리 할 수 없지만 getopts
올바른 작업을 수행합니다. 위 코드는 기본적으로 작동하지 않습니다 getopt
. GNU getopt
는 기본적으로 Linux에 설치되지만 Mac OS X 및 FreeBSD에는 별도로 설치해야합니다. Mac OS X의 경우 MacPorts ( http://www.macports.org ) sudo port install getopt
를 설치 한 다음 GNU getopt
(일반적으로로 /opt/local/bin
) 를 설치 하고 /opt/local/bin
셸 경로 앞에 있어야 합니다./usr/bin
. FreeBSD에서 설치하십시오 misc/getopt
.
자신의 프로그램에 대한 예제 코드를 수정하기위한 빠른 안내서 : 처음 몇 줄 중에서 모두 "보일러 판"은 호출하는 줄을 제외하고 동일하게 유지되어야합니다 getopt
. 뒤에 프로그램 이름을 변경하고 뒤에 -n
짧은 옵션을 지정 -o
하고 뒤에 긴 옵션을 지정해야 --long
합니다. 값을 취하는 옵션 뒤에 콜론을 넣으십시오.
마지막으로, set
대신에 코드가 있으면 eval set
BSD 용으로 작성된 것입니다 getopt
. eval set
두 가지 버전 모두에서 잘 작동 하는 스타일 을 사용하도록 변경해야 getopt
하지만 일반 set
은 GNU에서 제대로 작동하지 않습니다 getopt
.
1 실제로 는 긴 이름의 옵션 getopts
을 ksh93
지원하지만이 쉘은 자주 사용되지 않습니다 bash
. 에서 zsh
사용 zparseopts
이 기능을 얻을 수 있습니다.
2 기술적으로 "GNU getopt
"는 잘못된 이름입니다. 이 버전은 실제로 GNU 프로젝트가 아닌 Linux 용으로 작성되었습니다. 그러나 모든 GNU 규칙을 따르며 getopt
" GNU " 라는 용어 가 일반적으로 사용됩니다 (예 : FreeBSD에서).