
Linux 셸 스크립트가 명령줄 옵션과 인수를 보다 우아하게 처리하기를 원하십니까? 배쉬 getopts builtin을 사용하면 기교를 사용하여 명령줄 옵션을 구문 분석할 수 있으며 그것도 쉽습니다. 우리는 방법을 보여줍니다.
getopt 내장 소개
통과 가치 Bash 스크립트에 넣는 것은 꽤 간단한 문제입니다. 명령줄이나 다른 스크립트에서 스크립트를 호출하고 스크립트 이름 뒤에 값 목록을 제공합니다. 이 값은 스크립트 내에서 변수로 액세스할 수 있습니다. $1 첫 번째 변수에 대해, $2 두 번째 등등.
하지만 합격하고 싶다면 옵션 스크립트에 대한 상황은 빠르게 더 복잡해집니다. 옵션이라고 할 때 프로그램이 다음과 같은 옵션, 플래그 또는 스위치를 의미합니다. ls 다룰수있다. 대시 “-” 그리고 일반적으로 프로그램에 대한 표시기 역할을 하여 기능의 일부를 켜거나 끕니다.
그만큼 ls 명령에는 주로 출력 형식 지정과 관련된 50개 이상의 옵션이 있습니다. 그만큼 -X (확장자별 정렬) 옵션은 출력을 파일 확장자에 따라 알파벳순으로 정렬합니다. 그만큼 -U (정렬되지 않은) 옵션은 디렉토리 순서에 따라 나열됩니다.
옵션은 선택 사항일 뿐입니다. 사용자가 어떤 옵션을 사용할지(있는 경우) 알지 못하며 명령줄에 어떤 순서로 나열할지 모릅니다. 이것은 옵션을 구문 분석하는 데 필요한 코드의 복잡성을 증가시킵니다.
일부 옵션이 다음과 같은 인수를 취하면 상황이 더욱 복잡해집니다. 옵션 인수예를 들어, ls -w (width) 옵션은 출력의 최대 표시 너비를 나타내는 숫자가 뒤에 와야 합니다. 물론 옵션이 아닌 단순히 데이터 값인 다른 매개변수를 스크립트에 전달할 수도 있습니다.
고맙게도 getopts 이 복잡성을 처리합니다. 그리고 내장형이기 때문에 Bash 셸이 있는 모든 시스템에서 사용할 수 있으므로 설치할 필요가 없습니다.
참고: getopts getopt 아님
라는 오래된 유틸리티가 있습니다. getopt . 이것은 작은 유틸리티입니다 프로그램, 내장이 아닙니다. 의 다양한 버전이 있습니다 getopt 서로 다른 행동을 하는 반면, getops builtin은 POSIX 지침을 따릅니다.
type getopts
type getopt

때문에 getopt 기본 제공되지 않으며 자동 이점 중 일부를 공유하지 않습니다. getopts 예를 들어 공백을 현명하게 처리합니다. 와 함께 getopts, Bash 셸은 스크립트를 실행하고 Bash 셸은 옵션 구문 분석을 수행합니다. 구문 분석을 처리하기 위해 외부 프로그램을 호출할 필요가 없습니다.
절충안은 getopts 이중 대시의 긴 형식 옵션 이름은 처리하지 않습니다. 따라서 다음과 같은 형식의 옵션을 사용할 수 있습니다. -w 하지만 ” ---wide-format.” 반면에 옵션을 허용하는 스크립트가 있는 경우 -a , -b 그리고 , -cgetopts 당신이 그들을 결합 할 수 있습니다 -abc, -bca또는 -bac 등등.
논의하고 시연하고 있습니다. getopts 이 문서에서는 명령 이름에 마지막 “s”를 추가해야 합니다.
관련된: Windows 명령줄에서 파일 경로의 공백을 이스케이프하는 방법
요약: 매개변수 값 처리
이 스크립트는 다음과 같은 대시 옵션을 사용하지 않습니다. -a 또는 -b . 명령줄에서 “일반” 매개변수를 허용하고 스크립트 내에서 값으로 액세스합니다.
#!/bin/bash # get the variables one by one echo "Variable One: $1" echo "Variable Two: $2" echo "Variable Three: $3" # loop through the variables for var in "$@" do echo "$var" done
매개변수는 스크립트 내에서 변수로 액세스됩니다. $1, $2또는 $3 .
이 텍스트를 편집기에 복사하고 “variables.sh”라는 파일로 저장합니다. 우리는 그것을 실행 가능하게 만들어야 할 것입니다 chmod 명령. 논의하는 모든 스크립트에 대해 이 단계를 수행해야 합니다. 매번 적절한 스크립트 파일의 이름을 바꾸십시오.
chmod +x variables.sh

매개변수 없이 스크립트를 실행하면 이 출력을 얻습니다.
./variables.sh

스크립트에 보고할 값이 없으므로 매개변수를 전달하지 않았습니다. 이번에는 몇 가지 매개변수를 제공하겠습니다.
./variables.sh how to geek

예상대로 변수는 $1, $2 그리고 $3 매개변수 값으로 설정되었으며 인쇄된 것을 볼 수 있습니다.
이 유형의 일대일 매개변수 처리는 얼마나 많은 매개변수가 있는지 미리 알아야 함을 의미합니다. 스크립트 맨 아래에 있는 루프는 매개변수가 몇 개인지 상관하지 않고 항상 모든 매개변수를 반복합니다.
네 번째 매개변수를 제공하면 변수에 할당되지 않지만 루프는 여전히 이를 처리합니다.
./variables.sh how to geek website

두 단어 주위에 따옴표를 넣으면 하나의 매개변수로 처리됩니다.
./variables.sh how "to geek"

옵션, 인수가 있는 옵션 및 “일반” 데이터 유형 매개변수의 모든 조합을 처리하는 스크립트가 필요한 경우 일반 매개변수에서 옵션을 분리해야 합니다. 인수가 있든 없든 모든 옵션을 배치하여 이를 달성할 수 있습니다.~ 전에 일반 매개변수.
하지만 걷기 전에 뛰지 맙시다. 명령줄 옵션을 처리하는 가장 간단한 경우를 살펴보겠습니다.
취급 옵션
우리는 사용 getopts 안에 while 고리. 루프의 각 반복은 스크립트에 전달된 하나의 옵션에서 작동합니다. 각각의 경우 변수 OPTION 다음으로 식별되는 옵션으로 설정됩니다. getopts.
루프를 반복할 때마다 getopts 다음 옵션으로 넘어갑니다. 더 이상 선택지가 없을 때, getopts 보고 false 그리고 while 루프가 종료됩니다.
그만큼 OPTION 변수는 각 case 문 절의 패턴과 일치합니다. case 문을 사용하기 때문에 명령줄에서 옵션이 제공되는 순서는 중요하지 않습니다. 각 옵션이 case 문에 삭제되고 적절한 절이 트리거됩니다.
case 문의 개별 절을 사용하면 스크립트 내에서 옵션별 작업을 쉽게 수행할 수 있습니다. 일반적으로 실제 스크립트에서는 각 절에 변수를 설정하고 이러한 변수는 스크립트에서 추가로 플래그 역할을 하여 일부 기능을 허용하거나 거부합니다.
이 텍스트를 편집기에 복사하고 “options.sh”라는 스크립트로 저장하고 실행 가능하게 만드십시오.
#!/bin/bash
while getopts 'abc' OPTION; do
case "$OPTION" in
a)
echo "Option a used" ;;
b)
echo "Option b used"
;;
c)
echo "Option c used"
;;
?)
echo "Usage: $(basename $0) [-a] [-b] [-c]"
exit 1
;;
esac
done
이것은 while 루프를 정의하는 라인입니다.
while getopts 'abc' OPTION; do
그만큼 getopts 명령 뒤에 옵션 문자열. 이것은 우리가 옵션으로 사용할 문자를 나열합니다. 이 목록의 문자만 옵션으로 사용할 수 있습니다. 따라서 이 경우, -d 유효하지 않습니다. 이것은 덫에 걸렸을 것입니다. ?) 조항 때문에 getopts 물음표 “를 반환합니다.?” 미확인 옵션의 경우. 이 경우 올바른 사용법이 터미널 창에 인쇄됩니다.
echo "Usage: $(basename $0) [-a] [-b] [-c]"
관례에 따라 옵션을 대괄호 “로 묶습니다.[]” 이 유형의 올바른 사용법 메시지에서 옵션은 선택 사항임을 의미합니다. basename 명령은 파일 이름에서 모든 디렉토리 경로를 제거합니다. 스크립트 파일 이름은 $0 Bash 스크립트에서.
이 스크립트를 다른 명령줄 조합과 함께 사용하겠습니다.
./options.sh -a
./options.sh -a -b -c
./options.sh -ab -c
./options.sh -cab

보시다시피 옵션의 모든 테스트 조합은 구문 분석되고 올바르게 처리됩니다. 존재하지 않는 옵션을 시도하면 어떻게 될까요?
./options.sh -d

사용 절이 트리거되며 이는 양호하지만 셸에서 오류 메시지도 받습니다. 그것은 당신의 사용 사례에 중요할 수도 있고 중요하지 않을 수도 있습니다. 오류 메시지를 구문 분석해야 하는 다른 스크립트에서 스크립트를 호출하는 경우 셸에서도 오류 메시지를 생성하는 경우 더 어렵게 만듭니다.
쉘 오류 메시지를 끄는 것은 매우 쉽습니다. 우리가 해야 할 일은 콜론을 넣는 것뿐입니다.” : “를 옵션 문자열의 첫 번째 문자로 사용합니다.
“options.sh” 파일을 편집하고 옵션 문자열의 첫 번째 문자로 콜론을 추가하거나 이 스크립트를 “options2.sh”로 저장하고 실행 가능하게 만드십시오.
#!/bin/bash
while getopts ':abc' OPTION; do
case "$OPTION" in
a)
echo "Option a used"
;;
b)
echo "Option b used"
;;
c)
echo "Option c used"
;;
?)
echo "Usage: $(basename $0) [-a] [-b] [-c]"
exit 1
;;
esac
done
이것을 실행하고 오류를 생성하면 쉘 메시지 없이 자체 오류 메시지가 수신됩니다.
./options2.sh.sh -d

옵션 인수와 함께 getopts 사용
말하다 getopts 옵션 뒤에 인수가 오기 위해서는 콜론을 넣으십시오.” : ” 옵션 문자열의 옵션 문자 바로 뒤에 있습니다.
옵션 문자열에서 “b”와 “c” 뒤에 콜론을 붙이면, getopt 이러한 옵션에 대한 인수가 예상됩니다. 이 스크립트를 편집기에 복사하고 “arguments.sh”로 저장하고 실행 가능하게 만드십시오.
기억해, 첫 번째 옵션 문자열의 콜론은 쉘 오류 메시지를 억제하는 데 사용되며 인수 처리와 관련이 없습니다.
언제 getopt 인수가 있는 옵션을 처리하면 인수가 OPTARG 변하기 쉬운. 스크립트의 다른 곳에서 이 값을 사용하려면 다른 변수에 복사해야 합니다.
#!/bin/bash while getopts ':ab:c:' OPTION; do case "$OPTION" in a) echo "Option a used" ;; b) argB="$OPTARG" echo "Option b used with: $argB" ;; c) argC="$OPTARG" echo "Option c used with: $argC" ;; ?) echo "Usage: $(basename $0) [-a] [-b argument] [-c argument]" exit 1 ;; esac done
그것을 실행하고 그것이 어떻게 작동하는지 봅시다.
./arguments.sh -a -b "how to geek" -c reviewgeek
./arguments.sh -c reviewgeek -a

이제 명령줄에 지정된 순서에 관계없이 인수가 있거나 없는 옵션을 처리할 수 있습니다.
하지만 일반 매개변수는 어떻습니까? 우리는 이전에 옵션 뒤에 명령줄에 넣어야 한다는 것을 알고 있다고 말했습니다. 하면 어떻게 되는지 봅시다.
혼합 옵션 및 매개변수
한 줄 더 포함하도록 이전 스크립트를 변경합니다. 때 while 루프가 종료되고 모든 옵션이 처리되었으며 일반 매개변수에 액세스하려고 합니다. 우리는 값을 출력할 것입니다 $1 .
이 스크립트를 “arguments2.sh”로 저장하고 실행 가능하게 만드십시오.
#!/bin/bash while getopts ':ab:c:' OPTION; do case "$OPTION" in a) echo "Option a used" ;; b) argB="$OPTARG" echo "Option b used with: $argB" ;; c) argC="$OPTARG" echo "Option c used with: $argC" ;; ?) echo "Usage: $(basename $0) [-a] [-b argument] [-c argument]" exit 1 ;; esac done echo "Variable one is: $1"
이제 몇 가지 옵션과 매개변수 조합을 시도해 보겠습니다.
./arguments2.sh dave
./arguments2.sh -a dave
./arguments2.sh -a -c how-to-geek dave

이제 우리는 문제를 볼 수 있습니다. 옵션을 사용하자마자 변수 $1 이후는 옵션 플래그와 해당 인수로 채워집니다. 마지막 예에서, $4 매개변수 값 “dave”를 보유하지만 얼마나 많은 옵션과 인수가 사용될지 모르는 경우 스크립트에서 어떻게 액세스합니까?
사용하는 것이 답이다 OPTIND 그리고 shift 명령.
그만큼 shift 명령은 유형에 관계없이 매개변수 목록에서 첫 번째 매개변수를 버립니다. 다른 매개변수는 “셔플다운”하므로 매개변수 2는 매개변수 1이 되고 매개변수 3은 매개변수 2가 되는 식입니다. 그리고 그래서 $2 된다 $1 , $3 된다 $2 등등.
제공하는 경우 shift 숫자를 사용하면 목록에서 많은 매개변수를 제거합니다.
OPTIND 발견되고 처리되는 옵션과 인수를 계산합니다. 모든 옵션과 인수가 처리되면 OPTIND 옵션의 수보다 하나 더 높을 것입니다. 따라서 shift를 사용하여 트리밍하면 (OPTIND-1) 매개변수 목록에서 매개변수를 제거하면 일반 매개변수가 $1 앞으로.
이것이 바로 이 스크립트가 하는 일입니다. 이 스크립트를 “arguments3.sh”로 저장하고 실행 가능하게 만드십시오.
#!/bin/bash
while getopts ':ab:c:' OPTION; do
case "$OPTION" in
a)
echo "Option a used"
;;
b)
argB="$OPTARG"
echo "Option b used with: $argB"
;;
c)
argC="$OPTARG"
echo "Option c used with: $argC"
;;
?)
echo "Usage: $(basename $0) [-a] [-b argument] [-c argument]"
exit 1
;;
esac
done
echo "Before - variable one is: $1"
shift "$(($OPTIND -1))"
echo "After - variable one is: $1"
echo "The rest of the arguments (operands)"
for x in "$@"
do
echo $x
done
옵션, 인수 및 매개변수를 혼합하여 이것을 실행할 것입니다.
./arguments3.sh -a -c how-to-geek "dave dee" dozy beaky mick tich

우리는 우리가 전화하기 전에 그것을 볼 수 있습니다 shift , $1 “-a”를 유지했지만 shift 명령 후에 $1 첫 번째 비 옵션, 비 인수 매개 변수를 보유합니다. 옵션 구문 분석 없이 스크립트에서 하는 것처럼 쉽게 모든 매개변수를 반복할 수 있습니다.
항상 옵션이 있는 것이 좋습니다.
스크립트에서 옵션과 해당 인수를 처리하는 것은 복잡할 필요가 없습니다. 와 함께 getopts POSIX 호환 기본 스크립트와 똑같이 명령줄 옵션, 인수 및 매개 변수를 처리하는 스크립트를 만들 수 있습니다.








