if는 명령이 성공했는지 확인합니다
if 뒤에는 명령이 옵니다. 종료 상태가 0이면 then 부분을 실행합니다. 대괄호도 test와 같은 검사를 수행하는 명령이므로 인자 사이에 공백이 필요합니다.
value=12
if [ "$value" -gt 10 ]; then
printf '%s\n' 'greater than 10'
fi
if [ "$value" = 12 ] && [ -n "$value" ]; then
printf '%s\n' 'same text, not empty'
fi| 표현 | 검사하는 내용 |
|---|---|
-eq, -lt, -gt | 정수의 같음·작음·큼입니다. 임의 문자열을 바로 넣으면 숫자 검사에 실패할 수 있습니다. |
=, != | 문자열 비교입니다. [ … ]에서 숫자 크기를 비교할 때 >를 쓰면 리다이렉션으로 해석될 수 있습니다. |
-z, -n | 문자열이 비어 있는지, 비어 있지 않은지 확인합니다. |
&&, || | 앞 명령이 성공하거나 실패했을 때 뒤 명령을 실행합니다. XOR 연산자가 아닙니다. |
여러 조건은 [ … ] && [ … ]처럼 나누면 인자 수에 따라 의미가 달라지는 -a/-o 표현을 피할 수 있습니다. 검사만 성공했다고 뒤의 파일 작업까지 성공하는 것은 아닙니다.
break는 가장 가까운 반복문을 끝냅니다
for item in alpha stop omega; do
if [ "$item" = stop ]; then
break
fi
printf '%s\n' "$item"
done
printf '%s\n' donealpha와 done이 출력됩니다. if의 조건이 맞을 때 break를 실행하지만, 끝나는 대상은 for 반복문입니다. continue는 현재 반복의 나머지를 건너뜁니다. 루프 밖에서 break를 일반 분기 종료 명령처럼 쓰지 않습니다.
- item에 다음 값 저장alpha, stop, omega 순서로 후보를 받습니다.
- stop인지 검사참이면 반복문 밖으로 이동합니다.
- 그 밖의 값 출력다음 반복으로 돌아갑니다.
상자의 번호는 실행 순서입니다. stop에서 3번을 실행하지 않고 루프 뒤의 done 출력으로 이동합니다.
read의 실패와 빈 입력을 구분합니다
printf 'name: '
if IFS= read -r name; then
case "$name" in
'') printf '%s\n' 'empty input' ;;
quit|exit) printf '%s\n' 'stop requested' ;;
*) printf 'name=%s\n' "$name" ;;
esac
else
printf '%s\n' 'input ended before a complete line' >&2
fiIFS=는 양 끝의 공백을 보존하고, -r은 역슬래시를 이스케이프로 처리하지 않도록 합니다. Enter만 누른 빈 줄은 정상 입력입니다. EOF 등으로 read가 실패한 경우와 구분해야 합니다. 파일의 마지막 줄에 개행이 없으면 값이 들어와도 read가 실패할 수 있으므로 파일 순회에서는 그 경우를 별도로 처리합니다. case는 문자열과 패턴을 비교하며 ;;에서 해당 분기를 끝냅니다.
Bash 전용 문법과 출력·종료 처리를 구분합니다
#!/usr/bin/env bash
trap 'printf "%s\n" "interrupted" >&2; exit 130' INT
path='dir/sample.txt'
printf 'file=%s\n' "${path##*/}"
printf 'without extension=%s\n' "${path%.*}"
printf '%s\n' {one,two,three}##는 가장 길게 맞는 접두 패턴을, %는 가장 짧게 맞는 접미 패턴을 제거합니다. ${0%/*}도 문자열 처리이므로 슬래시가 없는 호출에서는 디렉터리를 알아내지 못합니다. pushd/popd, 브레이스 확장, 대소문자 변환 ${name^^}, [[ … ]], (( … ))는 sh에서 그대로 된다고 가정하지 않습니다.
trap은 지정한 시그널이나 셸 이벤트에서 실행할 명령을 등록합니다. SIGKILL과 SIGSTOP은 잡을 수 없습니다. EXIT trap도 전원 중단이나 SIGKILL까지 처리해 주지는 않습니다. echo의 -e 동작에 의존하기보다 printf에 고정된 형식과 값을 별도 인자로 전달합니다.