getopt그리고 getopts다른 짐승이 있고, 사람들은 무슨 오해의 조금을 갖고있는 것 같다. getopts는 bash명령 행 옵션을 루프로 처리하고 찾은 각 옵션과 값을 내장 변수에 차례로 지정하여 추가로 처리 할 수있는 내장 명령입니다. getopt그러나 외부 유틸리티 프로그램이며 bash , Perl 모듈 또는 Python / 모듈 과 같은 옵션을 실제로 처리하지는 않습니다 . 이 모든 수행은 규범화에게 전달되는 옵션입니다 - 즉, 그것이 그들을 처리하는 쉘 스크립트 쉽게 그래서, 더 표준 형태로 변환. 예를 들어의 응용 프로그램은 다음을 변환 할 수 있습니다.getoptsGetoptoptparseargparsegetoptgetopt
myscript -ab infile.txt -ooutfile.txt
이것으로 :
myscript -a -b -o outfile.txt infile.txt
실제 처리를 직접 수행해야합니다. getopt옵션을 지정할 수있는 방법에 대해 다양한 제한을 설정 한 경우 전혀 사용할 필요가 없습니다 .
- 인수 당 하나의 옵션 만 넣으십시오.
- 모든 옵션은 위치 매개 변수 (즉, 옵션이 아닌 인수)보다 우선합니다.
- 값이있는 옵션 (예 :
-o위)의 경우 값은 공백 뒤에 별도의 인수로 가야합니다.
왜 getopt대신에 사용 getopts합니까? 기본적인 이유는 GNU만이 getopt긴 이름의 명령 줄 옵션을 지원하기 때문입니다 . 1 ( getoptLinux에서는 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 setBSD 용으로 작성된 것입니다 getopt. eval set두 가지 버전 모두에서 잘 작동 하는 스타일 을 사용하도록 변경해야 getopt하지만 일반 set은 GNU에서 제대로 작동하지 않습니다 getopt.
1 실제로 는 긴 이름의 옵션 getopts을 ksh93지원하지만이 쉘은 자주 사용되지 않습니다 bash. 에서 zsh사용 zparseopts이 기능을 얻을 수 있습니다.
2 기술적으로 "GNU getopt"는 잘못된 이름입니다. 이 버전은 실제로 GNU 프로젝트가 아닌 Linux 용으로 작성되었습니다. 그러나 모든 GNU 규칙을 따르며 getopt" GNU " 라는 용어 가 일반적으로 사용됩니다 (예 : FreeBSD에서).