test와 대괄호 비교
if 다음에 오는 조건식을 어떻게 쓰느냐에 따라 Bash 스크립트의 안전성과 가독성이 크게 달라집니다. Bash에는 조건을 검사하는 방법이 세 가지 있습니다. test 명령어, 단일 대괄호 [ ], 이중 대괄호 [[ ]]입니다. 겉으로는 비슷해 보이지만 동작 방식에 중요한 차이가 있습니다.
test 명령어
test는 조건을 평가하는 내장 명령어입니다. 조건이 참이면 종료 코드 0을, 거짓이면 1을 반환합니다.
test -f /etc/hostsecho $? # 0 (참: 파일이 존재함)test -f /etc/notexistecho $? # 1 (거짓: 파일이 없음)
if와 함께 쓰면 이렇게 됩니다.
if test -f /etc/hosts; then echo "파일이 있습니다."fi
단일 대괄호 [ ]
[ ]는 test 명령어의 또 다른 이름입니다. 문법적으로 완전히 동일하게 동작합니다.
if [ -f /etc/hosts ]; then echo "파일이 있습니다."fi
[와 ] 안쪽에는 반드시 공백이 있어야 합니다. [-f /etc/hosts]처럼 붙이면 오류가 납니다. [는 명령어고, 그 다음 인자들과 공백으로 구분되어야 하기 때문입니다.
이중 대괄호 [[ ]]
[[ ]]는 Bash가 직접 제공하는 키워드입니다. [ ]와 비슷해 보이지만 훨씬 강력하고 안전합니다.
if [[ -f /etc/hosts ]]; then echo "파일이 있습니다."fi
[ ] vs [[ ]] 핵심 차이
1. 따옴표 없이도 안전합니다.
[ ]에서 변수에 따옴표를 빠뜨리면 공백이 포함된 값이 여러 단어로 쪼개져서 오류가 납니다.
filename="my file.txt"# [ ]에서는 따옴표 필수[ -f $filename ] # 오류: [ -f my file.txt ]로 해석됨[ -f "$filename" ] # 정상# [[ ]]에서는 따옴표 없어도 안전[[ -f $filename ]] # 정상: $filename을 하나의 단어로 처리
2. 패턴 매칭을 지원합니다.
[[ ]]는 == 오른쪽에 글로브 패턴을 쓸 수 있습니다.
filename="report_2024.txt"if [[ $filename == *.txt ]]; then echo "텍스트 파일입니다."fi
3. 정규식 매칭을 지원합니다.
=~ 연산자로 정규식을 직접 쓸 수 있습니다.
phone="010-1234-5678"if [[ $phone =~ ^010-[0-9]{4}-[0-9]{4}$ ]]; then echo "올바른 전화번호 형식입니다."fi
4. && 와 || 를 직접 쓸 수 있습니다.
[ ]에서는 -a(AND)와 -o(OR)를 써야 하지만, [[ ]]에서는 &&와 ||를 그대로 씁니다.
age=25name="Alice"# [ ]에서의 ANDif [ $age -ge 18 -a -n "$name" ]; then ...# [[ ]]에서의 AND (더 직관적)if [[ $age -ge 18 && -n "$name" ]]; then ...
세 가지 비교표
| 기능 | test | [ ] | [[ ]] |
|---|---|---|---|
| 기본 조건 검사 | 지원 | 지원 | 지원 |
| POSIX 호환 | 지원 | 지원 | 미지원 (Bash 전용) |
| 따옴표 없는 변수 | 위험 | 위험 | 안전 |
| 글로브 패턴 매칭 | 미지원 | 미지원 | 지원 (==) |
| 정규식 매칭 | 미지원 | 미지원 | 지원 (=~) |
| && / || 사용 | 미지원 | 미지원 | 지원 |
| -a / -o 사용 | 지원 | 지원 | 미지원 (비권장) |
[[ ]] 권장 이유와 예외
Bash 스크립트를 작성한다면 [[ ]]를 기본으로 사용하는 것이 좋습니다. 패턴 매칭, 정규식, 안전한 변수 처리 모두 [[ ]]가 우월합니다.
단, POSIX 쉘(/bin/sh)에서도 동작해야 하는 스크립트, 예를 들어 시스템 초기화 스크립트나 다양한 유닉스 환경에서 실행되는 스크립트라면 [ ]를 써야 합니다. [[ ]]는 Bash, Zsh 등에서만 동작하고 순수 POSIX 쉘에서는 동작하지 않기 때문입니다.
#!/bin/bash # Bash 전용 → [[ ]] 사용 권장#!/bin/sh # POSIX 쉘 → [ ] 또는 test 사용
스크립트 첫 줄의 셔뱅을 보고 적절한 방식을 선택하면 됩니다. 이 교재에서는 #!/bin/bash를 기본으로 사용하므로 [[ ]]를 권장합니다.