모양
if [[ 조건 ]]; then
# ...
elif [[ 다른 조건 ]]; then
# ...
else
# ...
fiif는 참·거짓 값을 따로 받지 않고 명령의 종료 상태를 봐. 0이면 then, 0이 아니면 else로 가. [[ ... ]]는 bash와 zsh가 제공하는 조건 구문이라 패턴과 정규식 같은 기능이 풍부하지만, POSIX sh에서는 쓸 수 없어.
문자열 테스트
[[ -z "$x" ]]: 비어 있음.[[ -n "$x" ]]: 비어 있지 않음.[[ "$a" == "$b" ]]: 같음.[[ "$a" != "$b" ]]: 다름.[[ "$x" == prefix* ]]: 글로브 매치 ([[ ]] 안에서만).[[ "$x" =~ ^[0-9]+$ ]]: 정규식 매치 (bash/zsh).
숫자 테스트
[[ $a -eq $b ]]: 같음 (eq, ne, lt, le, gt, ge).(( a == b )): 산술 맥락 (수학에 더 깔끔).
파일 테스트
[[ -f path ]]: 일반 파일 존재.[[ -d path ]]: 디렉터리.[[ -e path ]]: 존재 (타입 무관).[[ -r path ]],-w,-x: 읽기 / 쓰기 / 실행.[[ -s path ]]: 존재 + 비어 있지 않음.
논리 연산자를 조합해
if [[ -f config.yaml && -r config.yaml ]]; then ...
if [[ -z "$NAME" || -z "$EMAIL" ]]; then ...[[ ]] 안에선 &&, || 사용. 밖에선 명령 자체를 체이닝.
조건식보다 종료 상태가 먼저야
if grep -q pattern file; then처럼 명령을 그대로 조건으로 쓰면 굳이 $?를 중간 변수에 담지 않아도 돼. 다만 ‘찾지 못함’과 ‘파일을 읽지 못함’이 서로 다른 종료 상태를 쓰는 명령도 있어. 중요한 분기라면 매뉴얼 페이지에서 상태 값을 확인하고, 모든 0 아닌 값을 같은 실패로 뭉개지 마.
패턴과 문자열을 구분해
[[ $x == prefix* ]]에서 오른쪽의 별표는 패턴이지만 [[ $x == "$literal" ]]처럼 인용하면 글자 그대로 비교해. 같은 기호가 문맥에 따라 역할을 바꾸므로, 비교하려는 것이 값인지 패턴인지 먼저 정하는 습관이 필요해.