위치 매개변수 마스터하기: Bash 스크립트 인수에 대한 가이드
Bash 스크립트는 외부 입력을 받아 처리할 수 있을 때 엄청난 힘과 유연성을 얻습니다. 명령줄 인수—스크립트가 실행될 때 전달되는 데이터—는 사용자가 자동화 도구와 상호 작용하고 사용자 정의하는 기본적인 방법입니다. 이러한 입력을 Bash가 어떻게 처리하는지 마스터하는 것은 강력하고 재사용 가능하며 전문적인 스크립트를 작성하는 데 중요합니다.
이 가이드에서는 Bash가 명령줄 인수에 액세스하는 데 사용하는 특수 변수($1, $2, $@, $#)인 위치 매개변수에 대한 포괄적인 개요를 제공합니다. 이러한 변수에 액세스하는 메커니즘을 탐색하고, 중요한 따옴표 동작을 구분하며, 입력 유효성 검사 및 반복을 위한 모범 사례를 구현할 것입니다.
위치 매개변수의 구조
위치 매개변수는 셸에서 정의한 특수 변수로, 스크립트 이름 뒤에 오는 명령줄에 제공된 단어에 해당합니다. 이들은 1부터 순차적으로 번호가 매겨집니다.
| 매개변수 | 설명 | 예시 값 ( ./script.sh file1 dir/ 실행 시) |
|---|---|---|
$0 |
스크립트 자체 또는 함수의 이름입니다. | ./script.sh |
$1 |
스크립트에 전달된 첫 번째 인수입니다. | file1 |
$2 |
스크립트에 전달된 두 번째 인수입니다. | dir/ |
$N |
N번째 인수 (N > 0). | |
${10} |
9개를 초과하는 인수는 중괄호로 묶어야 합니다. |
$9를 초과하는 인수 액세스
1부터 9까지의 인수는 $1부터 $9까지 직접 액세스하지만, 10번째 인수 및 그 이후의 인수에 액세스하려면 환경 변수나 문자열 작업과의 혼동을 방지하기 위해 숫자를 중괄호로 묶어야 합니다(예: $10 대신 ${10}).
스크립팅을 위한 필수 특수 매개변수
숫자 매개변수 외에도 Bash는 인수 집합 전체와 관련된 몇 가지 중요한 특수 변수를 제공합니다. 이들은 유효성 검사 및 반복에 필수적입니다.
1. 인수 개수 세기 ($#)
특수 변수 $#는 스크립트에 전달된 명령줄 인수의 총 개수( $0 제외)를 보유합니다. 이는 입력 유효성 검사를 구현하는 데 아마도 가장 중요한 변수일 것입니다.
#!/bin/bash
if [ "$#" -eq 0 ]; then
echo "오류: 인수가 제공되지 않았습니다."
echo "사용법: $0 <input_file>"
exit 1
fi
echo "$#개의 인수를 제공했습니다."
2. 모든 인수 ($@ 및 $*)
$@ 및 $* 변수는 모두 인수의 전체 목록을 나타내지만, 특히 따옴표로 묶을 때 다르게 동작합니다.
$* (단일 문자열)
이중 따옴표("$*")로 묶으면, 위치 매개변수의 전체 목록이 IFS(내부 필드 구분 기호) 변수의 첫 번째 문자(일반적으로 공백)로 구분된 단일 인수로 처리됩니다.
- 입력 인수가 다음과 같은 경우:
arg1arg2arg3 "$*"는 다음과 같이 확장됩니다:"arg1 arg2 arg3"(하나의 단일 요소)
$@ (개별 문자열 - 권장)
이중 따옴표("$@")로 묶으면, 각 위치 매개변수가 별도의 따옴표로 묶인 인수로 처리됩니다. 이는 공백을 포함하는 인수를 올바르게 보존하므로 인수를 반복하는 표준적이고 권장되는 방법입니다.
- 입력 인수가 다음과 같은 경우:
arg1"arg with space"arg3 "$@"는 다음과 같이 확장됩니다:"arg1" "arg with space" "arg3"(세 개의 별도 요소)
따옴표가 중요한 이유: 시연
인수와 함께 실행된 스크립트를 고려해 보세요: ./test.sh 'hello world' file.txt
#!/bin/bash
# "$*"를 사용한 루프 ( 'hello world'를 잘못 분할)
echo "-- \$* 사용 루프 ( 'hello world'를 잘못 분할) --"
for item in $*; do
echo "항목: $item"
done
# "\$@"를 사용한 루프 (인수를 올바르게 보존)
echo "-- "\$@" 사용 루프 (인수를 보존) --"
for item in "$@"; do
echo "항목: $item"
done
첫 번째 루프에서 항목: hello 및 항목: world의 출력은 "$@"가 필수적인 이유를 보여줍니다.
인수 처리를 위한 실용적인 기법
1. 기본 인수 검색 스크립트
이 간단한 스크립트는 특정 매개변수에 액세스하고 $0을 사용하여 유용한 피드백을 제공하는 방법을 보여줍니다.
deploy_service.sh:
#!/bin/bash
# 사용법: deploy_service.sh <service_name> <environment>
SERVICE_NAME="$1"
ENVIRONMENT="$2"
# 유효성 검사 (최소 두 개의 인수)
if [ "$#" -lt 2 ]; then
echo "사용법: $0 <service_name> <environment>"
exit 1
fi
echo "서비스 배포 시작: $SERVICE_NAME"
echo "대상 환경: $ENVIRONMENT"
# 검증된 매개변수를 사용하여 명령 실행
ssh admin@server-"$ENVIRONMENT" "/path/to/start $SERVICE_NAME"
2. 강력한 입력 유효성 검사
좋은 스크립트는 항상 진행하기 전에 입력을 유효성 검사합니다. 여기에는 개수($#) 확인과 종종 인수의 내용 확인(예: 인수가 숫자 또는 유효한 파일 경로인지 확인)이 포함됩니다.
#!/bin/bash
# 1. 인수 개수 확인 (정확히 3개여야 함)
if [ "$#" -ne 3 ]; then
echo "오류: 이 스크립트에는 세 개의 인수(소스, 대상, 사용자)가 필요합니다."
echo "사용법: $0 <src_path> <dest_path> <user>"
exit 1
fi
SRC_PATH="$1"
DEST_PATH="$2"
USER="$3"
# 2. 내용 확인 (예: 소스 경로 존재 여부 확인)
if [ ! -f "$SRC_PATH" ]; then
echo "오류: 소스 파일 '$SRC_PATH'를 찾을 수 없거나 파일이 아닙니다."
exit 2
fi
# 유효성 검사가 통과되면 진행
echo "$SRC_PATH를 사용자 $USER로 $DEST_PATH에 복사 중..."
모범 사례 팁: 유효성 검사가 실패할 때 항상 명확하고 간결한
Usage:문구를 제공하세요. 이렇게 하면 사용자가 명령 호출을 신속하게 수정할 수 있습니다.
3. shift를 사용한 인수 반복
shift 명령은 인수를 순차적으로 처리하는 훌륭한 도구로, 간단한 플래그를 처리하거나 while 루프 내에서 인수를 하나씩 처리할 때 자주 사용됩니다.
shift는 현재 $1 인수를 삭제하고, $2를 $1로, $3를 $2로 이동시키며, $#를 1 감소시킵니다. 이렇게 하면 첫 번째 인수를 처리한 다음 인수가 남아 있지 않을 때까지 루프를 실행할 수 있습니다.
#!/bin/bash
# 간단한 -v 플래그를 처리한 다음 나머지 파일을 나열합니다.
VERBOSE=false
if [ "$1" = "-v" ]; then
VERBOSE=true
shift # -v 플래그를 삭제하고 인수를 위로 이동
fi
if $VERBOSE; then
echo "상세 모드가 활성화되었습니다."
fi
if [ "$#" -eq 0 ]; then
echo "파일이 지정되지 않았습니다."
exit 0
fi
echo "남은 $#개의 파일을 처리 중입니다:"
for file in "$@"; do
if $VERBOSE; then
echo "파일 확인 중: $file"
fi
# ... 처리 로직은 여기에
done
참고:
shift는 간단한 인수 파싱에 유용하지만, 여러 플래그와 옵션(예:-a,--help)을 포함하는 복잡한 스크립트의 경우, 짧은 옵션에는getopts또는 긴 옵션에는getopt와 같은 전문 도구를 사용하는 것이 좋습니다.
요약 및 다음 단계
위치 매개변수는 대화형 및 구성 가능한 Bash 스크립팅의 기초입니다. $1, $2, $# 및 가장 중요하게는 "$@"를 올바르게 활용하면 공백이나 특수 문자를 포함한 인수를 포함하여 사용자 입력을 안정적으로 처리하는 스크립트를 보장할 수 있습니다.
항상 스크립트 시작 부분에서 $#를 사용하여 입력 유효성을 검사하는 것을 우선시하여 나중에 예상치 못한 오류를 방지하세요. 추가 학습을 위해 getopts 내장 명령을 탐색하여 명령줄 플래그와 옵션을 전문적으로 처리하고 인수 처리 기능을 한 단계 더 발전시키세요.