getopts로 플래그와 인수 파싱하기
짧은 옵션, 필수 인수 및 사용법 메시지에 getopts를 사용하여 전문적인 명령줄 인터페이스를 구현하는 방법을 배웁니다.
getopts로 플래그와 인수 파싱하기은(는) CoddyKit의 무료 Linux Command Line & Bash Scripting Mastery 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Linux Command Line & Bash Scripting Mastery 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Linux Command Line & Bash Scripting Mastery 강의에는 총 4개의 강의가 포함되어 있습니다.
getopts가 존재하는 이유
실제 환경에서 사용하는 모든 스크립트는 결국 -v, -o output.txt 또는 -n 5와 같은 옵션을 받아야 합니다. 이러한 옵션을 $1, $2…로 직접 파싱하면 빠르게 취약해집니다.
getopts는 짧은 옵션(-a, -b)을 안정적으로 처리하는 POSIX 표준 내장 명령이며, 인수를 받는 옵션도 처리합니다. 모든 POSIX 셸에 내장되어 있으므로 별도의 의존성이 필요하지 않습니다.
- 결합된 플래그 처리:
-vn 5=-v -n 5 - 알 수 없는 옵션을 적절히 보고
- 표준 변수
OPTIND및OPTARG를 자동으로 설정
이 강의에서는 처음부터 getopts를 사용하여 완전하고 전문적인 명령줄 인터페이스를 만듭니다.
getopts 구문
핵심 구문은 반복할 때마다 getopts를 호출하는 while 루프입니다.
while getopts "optstring" varname; do
case "$varname" in
...
esac
done- 옵션 문자열 — 허용되는 각 옵션 문자를 나열한 문자열입니다. 문자 뒤의 콜론은 해당 옵션에 인수가 필요하다는 뜻입니다.
- 옵션 변수 이름 — 각 반복에서 현재 옵션 문자를 받습니다.
- OPTARG — 문자 뒤에 콜론이 있을 때 인수 값으로 자동 설정됩니다.
- OPTIND — 처리할 다음 인수의 인덱스입니다. 루프 뒤에
shift $((OPTIND - 1))를 사용하면 남은 위치 매개변수를 사용할 수 있습니다.
#!/usr/bin/env bash
# Minimal skeleton — shows the loop structure
while getopts 'vn:' opt; do
case "$opt" in
v) echo "Verbose mode on" ;;
n) echo "Count = $OPTARG" ;;
?) echo "Unknown option: -$OPTARG" >&2; exit 1 ;;
esac
done옵션 문자열 정의하기
옵션 문자열은 명령줄 인터페이스 계약을 간결하게 선언한 것입니다. 각 문자는 허용되는 하나의 플래그를 나타냅니다.
'abc'—-a,-b,-c를 인수 없이 허용합니다.'a:bc'—-a에는 인수가 필요하며,-b와-c에는 필요하지 않습니다.':abc'— 앞의 콜론은 무음 오류 모드를 활성화합니다. 셸이 메시지를 출력하는 대신 스크립트가 잘못된 옵션을 처리합니다.
무음 모드는 오류 메시지와 종료 코드를 완전히 제어할 수 있으므로 운영 환경의 스크립트에서 선호됩니다.
#!/usr/bin/env bash
# optstring ':o:vq'
# -o requires an argument (output file)
# -v verbose flag (no argument)
# -q quiet flag (no argument)
# Leading ':' = silent error mode
while getopts ':o:vq' opt; do
case "$opt" in
o) OUTPUT="$OPTARG" ;;
v) VERBOSE=1 ;;
q) QUIET=1 ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
echo "OUTPUT=$OUTPUT VERBOSE=$VERBOSE QUIET=$QUIET"OPTARG와 필수 인수
옵션 문자열에서 플래그 뒤에 콜론이 오면 getopts는 해당 값을 OPTARG에 저장합니다. 사용자는 공백을 넣거나 넣지 않고 인수를 작성할 수 있습니다.
-o report.txt-oreport.txt
두 형식은 동일하게 파싱됩니다. 이는 수동으로 $1/shift를 파싱하는 방식보다 중요한 장점입니다.
무음 모드(옵션 문자열이 ':'로 시작하는 경우)에서는 인수가 누락되면 getopts가 varname을 :로, OPTARG를 옵션 문자로 설정합니다. 따라서 대상이 명확한 오류 메시지를 만들기에 적합합니다.
#!/usr/bin/env bash
# Demonstrate OPTARG with a file-processing script
while getopts ':i:o:' opt; do
case "$opt" in
i) INPUT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
:) echo "Error: option -$OPTARG needs a value" >&2; exit 1 ;;
\?) echo "Error: unknown flag -$OPTARG" >&2; exit 1 ;;
esac
done
echo "Input : ${INPUT:-<not set>}"
echo "Output : ${OUTPUT:-<not set>}"OPTIND로 옵션 지나가기
getopts가 끝나면 OPTIND에는 첫 번째 옵션이 아닌 인수의 인덱스가 들어 있습니다. shift를 사용하여 처리된 모든 옵션을 제거하면 $1, $2…가 남은 위치 매개변수(예: 파일 이름)를 가리키게 됩니다.
항상 사용하는 관용구는 다음과 같습니다.
shift $((OPTIND - 1))이동한 뒤에는 $@에 플래그가 아닌 인수, 즉 명령의 피연산자만 들어 있습니다.
#!/usr/bin/env bash
# Shows OPTIND shift and leftover positional args
VERBOSE=0
while getopts ':vn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG requires an argument" >&2; exit 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "VERBOSE=$VERBOSE COUNT=${COUNT:-1}"
echo "Remaining args: $*"사용법 함수 작성하기
전문적인 스크립트는 항상 도움말 메시지를 출력하고 종료하는 usage() 함수를 제공합니다. 일반적인 규칙은 다음과 같습니다.
- 파이프로 전달된 출력을 오염시키지 않도록 표준 오류(fd 2)에 출력합니다.
-h/--help에는 종료 코드 0을, 잘못된 사용법에는 종료 코드 1을 사용합니다.- 오류 경로에서는
usage 1을,-h처리기에서는usage 0을 호출합니다.
#!/usr/bin/env bash
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-n COUNT] [-o FILE] [FILE...]
Options:
-v Verbose output
-n COUNT Repeat COUNT times (default: 1)
-o FILE Write output to FILE
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTFILE="$OPTARG" ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
echo "Parsed OK — verbose=${VERBOSE:-0} count=${COUNT:-1} out=${OUTFILE:--}"기본값과 검증
파싱이 끝나면 실제 작업을 수행하기 전에 값을 검증하고 기본값을 설정하십시오. 파싱 단계(루프)와 논리 단계를 분리하십시오. 그러면 두 부분을 모두 더 쉽게 읽고 테스트할 수 있습니다.
- 인라인 기본값에는
${VAR:-default}를 사용합니다. - 정규 표현식이나 산술 검사를 사용하여 숫자 인수를 검증합니다.
- 필수 옵션이 실제로 제공되었는지 확인합니다.
#!/usr/bin/env bash
usage() { echo "Usage: $(basename "$0") -n COUNT [-v]" >&2; exit 1; }
VERBOSE=0
COUNT=''
while getopts ':n:v' opt; do
case "$opt" in
n) COUNT="$OPTARG" ;;
v) VERBOSE=1 ;;
:) echo "Error: -$OPTARG needs a value" >&2; usage ;;
\?) echo "Error: -$OPTARG unknown" >&2; usage ;;
esac
done
shift $((OPTIND - 1))
# Validation phase
[[ -z "$COUNT" ]] && { echo "Error: -n COUNT is required" >&2; usage; }
[[ "$COUNT" =~ ^[0-9]+$ ]] || { echo "Error: COUNT must be a positive integer" >&2; usage; }
for (( i=1; i<=COUNT; i++ )); do
[[ $VERBOSE -eq 1 ]] && echo "Iteration $i of $COUNT"
echo "Hello, world!"
done명령줄에서 플래그 결합하기
getopts는 공백 없이 작성된 결합된 짧은 플래그를 자동으로 처리합니다. 이는 표준 Unix 규칙입니다.
-v -q는-vq와 같습니다.-n 5 -v는-n5 -v또는-vn5와 같습니다.
이를 지원하기 위한 추가 코드를 작성할 필요가 없습니다. getopts가 결합된 옵션 문자열의 각 문자를 자동으로 순회합니다. 수동 파싱 대신 getopts를 사용하는 또 하나의 중요한 이유입니다.
#!/usr/bin/env bash
# Test combined flag parsing
# Run as: bash script.sh -vq -n3
VERBOSE=0; QUIET=0; COUNT=1
while getopts ':vqn:' opt; do
case "$opt" in
v) VERBOSE=1 ;;
q) QUIET=1 ;;
n) COUNT="$OPTARG" ;;
:) echo "Error: -$OPTARG needs value" >&2; exit 1 ;;
\?) echo "Error: unknown -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
echo "verbose=$VERBOSE quiet=$QUIET count=$COUNT"이중 대시 구분 기호 처리하기
Unix 명령은 옵션 처리를 중지하라는 명시적 신호로 --(이중 대시)를 허용합니다. -- 뒤의 모든 항목은 플래그처럼 보이더라도 위치 인수로 처리됩니다.
getopts는 --를 만나면 자동으로 중지합니다. shift $((OPTIND - 1))를 실행한 뒤에는 이중 대시가 사라지고 $@에는 피연산자만 들어 있습니다.
다음과 같이 대시로 시작할 수 있는 파일 이름을 대상으로 작업하는 스크립트에서 특히 중요합니다.
myscript.sh -v -- -strangefile.txt#!/usr/bin/env bash
# Demonstrate -- separator
# Run as: bash script.sh -v -- file1.txt -oddname.txt
VERBOSE=0
while getopts ':v' opt; do
case "$opt" in
v) VERBOSE=1 ;;
\?) echo "Unknown option -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1)) # removes -v and the '--' separator
echo "Verbose: $VERBOSE"
echo "Files to process:"
for f in "$@"; do
echo " -> $f"
done라이브러리 함수로 getopts 감싸기
모듈식 스크립트에서는 getopts를 parse_args() 함수 안에 캡슐화하여 전역 변수(또는 nameref 변수)를 설정할 수 있습니다. 이렇게 하면 main()을 깔끔하게 유지하고 다른 스크립트에서 파서를 소스로 불러올 수 있습니다.
이 패턴의 핵심 규칙은 다음과 같습니다.
- 함수를 호출하기 전에 옵션 변수를 선언합니다.
global변수를 사용하거나 nameref(declare -n)를 통해 값을 전달합니다.- 잘못된 입력에서는 0이 아닌 종료 코드를 반환하여
main이 대응할 수 있게 합니다.
#!/usr/bin/env bash
# Global option variables
VERBOSE=0; OUTPUT=''; COUNT=1
parse_args() {
local opt
while getopts ':vn:o:h' opt; do
case "$opt" in
v) VERBOSE=1 ;;
n) COUNT="$OPTARG" ;;
o) OUTPUT="$OPTARG" ;;
h) echo "Usage: $(basename "$0") [-v] [-n N] [-o FILE]"; exit 0 ;;
:) echo "Error: -$OPTARG needs a value" >&2; return 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; return 1 ;;
esac
done
shift $((OPTIND - 1))
ARGS=("$@") # leftover positional args stored in array
}
main() {
parse_args "$@" || exit 1
echo "verbose=$VERBOSE count=$COUNT output=${OUTPUT:--} args=${ARGS[*]}"
}
main "$@"실제적인 전체 예제: 로그 보관 도구
이 강의에서 다룬 모든 내용을 사용하는 완전한 실제 스크립트입니다. 필수 인수가 있는 옵션 문자열, 무음 오류 모드, 사용법 함수, 기본값, 검증 및 OPTIND 이동을 포함합니다.
구조를 자세히 살펴보십시오. 명령줄 인터페이스가 필요한 모든 스크립트에서 따라야 할 기본 틀입니다.
#!/usr/bin/env bash
# archive_logs.sh — compress and move logs older than N days
set -euo pipefail
DESTDIR='/tmp/log_archive'
DAYS=30
VERBOSE=0
usage() {
cat >&2 <<EOF
Usage: $(basename "$0") [-v] [-d DAYS] [-o DIR] SOURCE_DIR
-d DAYS Archive logs older than DAYS (default: 30)
-o DIR Destination directory (default: /tmp/log_archive)
-v Verbose output
-h Show this help
EOF
exit "${1:-0}"
}
while getopts ':d:o:vh' opt; do
case "$opt" in
d) DAYS="$OPTARG" ;;
o) DESTDIR="$OPTARG" ;;
v) VERBOSE=1 ;;
h) usage 0 ;;
:) echo "Error: -$OPTARG requires a value" >&2; usage 1 ;;
\?) echo "Error: unknown option -$OPTARG" >&2; usage 1 ;;
esac
done
shift $((OPTIND - 1))
# Validation
[[ $# -lt 1 ]] && { echo "Error: SOURCE_DIR is required" >&2; usage 1; }
[[ "$DAYS" =~ ^[0-9]+$ ]] || { echo "Error: DAYS must be numeric" >&2; exit 1; }
SOURCE="$1"
[[ -d "$SOURCE" ]] || { echo "Error: '$SOURCE' is not a directory" >&2; exit 1; }
mkdir -p "$DESTDIR"
[[ $VERBOSE -eq 1 ]] && echo "Archiving logs older than $DAYS days from $SOURCE to $DESTDIR"
find "$SOURCE" -name '*.log' -mtime "+$DAYS" -print | while read -r f; do
gzip -c "$f" > "$DESTDIR/$(basename "$f").gz"
[[ $VERBOSE -eq 1 ]] && echo " archived: $f"
done
echo "Done."빠른 확인: getopts 옵션 문자열
다음 getopts 호출을 읽고 동작에 대한 올바른 설명을 선택하십시오.
while getopts ':f:vq' opt; do강의 요약: getopts 완전 정복
getopts를 사용하여 Bash에서 전문적인 명령줄 인터페이스를 만드는 방법을 배웠습니다. 핵심 내용을 요약하면 다음과 같습니다.
- 옵션 문자열 구문 — 콜론이 없는 문자는 불리언 플래그이고, 문자 뒤의 콜론은 인수가 필요하다는 뜻이며, 앞의 콜론은 무음 오류 모드를 활성화합니다.
- OPTARG — 인수가 필요한 옵션의 인수 값을 자동으로 보관합니다.
- OPTIND — 루프 뒤에
shift $((OPTIND - 1))를 사용하여 남은 위치 매개변수를$@에서 사용할 수 있게 합니다. - 무음 오류 모드 — 운영 환경에서 선호됩니다.
:(인수 누락) 및\?(알 수 없는 옵션) 경우를 직접 처리하여 완전히 제어하십시오. - usage() 함수 — 항상 작성하십시오. 표준 오류에 출력하고,
-h에는 0으로, 오류에는 1로 종료합니다. - 결합된 플래그 — getopts는 추가 코드 없이
-vq및-n5를 자동으로 처리합니다. - 모듈식 패턴 — 깔끔하고 재사용 가능한 스크립트를 위해 getopts를
parse_args()함수로 감쌉니다.
getopts를 완전히 익히면 스크립트가 단일 목적 도구에서 Unix 규칙을 따르는 안정적이고 사용자 친화적인 명령줄 프로그램으로 발전합니다.
AI 튜터와 함께 Bash을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 22
- 레슨
- 88
자주 묻는 질문
“getopts로 플래그와 인수 파싱하기” 강의는 무료인가요?
네 — “getopts로 플래그와 인수 파싱하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Linux Command Line & Bash Scripting Mastery 강의 전체를 잠금 해제할 수 있습니다. Linux Command Line & Bash Scripting Mastery 강의에는 총 4개의 강의가 포함되어 있습니다.
“getopts로 플래그와 인수 파싱하기”에서 뭘 배우나요?
짧은 옵션, 필수 인수 및 사용법 메시지에 getopts를 사용하여 전문적인 명령줄 인터페이스를 구현하는 방법을 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 Linux Command Line & Bash Scripting Mastery을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Linux Command Line & Bash Scripting Mastery을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Linux Command Line & Bash Scripting Mastery은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“getopts로 플래그와 인수 파싱하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Linux Command Line & Bash Scripting Mastery 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Linux Command Line & Bash Scripting Mastery 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 로컬 범위와 반환 코드로 함수 설계하기
- 재사용 가능한 Bash 라이브러리 구축과 불러오기
- getopts로 플래그와 인수 파싱하기
- 함수 간 배열과 연관 맵 전달하기