$( ): 명령 출력 캡처
now="$(date +%Y-%m-%d)"
files="$(find . -name '*.py' | wc -l)"
echo "$files Python files as of $now"$(...)는 명령을 실행하고 표준 출력을 값으로 치환해. 출력 끝의 줄바꿈은 제거돼. 결과를 인자 하나로 보존하려면 "$(cmd)"처럼 인용해. 인용하지 않으면 값이 단어로 나뉠 수 있어.
역따옴표로 쓰는 옛 명령 치환
옛 스크립트에는 cmd를 역따옴표로 감싼 표기가 남아 있어. 중첩과 인용이 읽기 어려우므로 새 코드는 $(cmd)를 쓰는 편이 분명해.
(( )): 산술
i=0
((i++))
((sum = a + b * 2))
((i < 10)) && echo 'still small'(( )) 안에서는 변수 이름 앞에 $를 붙이지 않아. 기본 산술 연산자와 ++, -- 같은 C 계열 연산자를 사용할 수 있어. 계산 결과가 0이 아니면 종료 상태 0을, 결과가 0이면 종료 상태 1을 반환해.
$(( )): 산술 치환
echo "$((1 + 2))" # 3
echo "file_$((i + 1)).txt"계산한 정수를 문자열 안에 넣을 때 써. 파일명이나 카운터를 만들 때 유용해.
Bash 산술은 정수만 다뤄
셸 산술은 정수만 다뤄. 소수 계산이 필요하면 bc -l이나 awk 'BEGIN{print 3.14*2}'를 사용할 수 있지만, 계산이 복잡해지면 Python 같은 언어로 옮기는 편이 명확해.
캡처하면 끝의 줄바꿈은 사라져
명령 치환은 출력 끝에 붙은 줄바꿈을 제거해. 사람이 보는 한 줄 결과에는 편하지만, 원본 텍스트의 끝을 그대로 보존해야 하는 작업에는 맞지 않을 수 있어. NUL 바이트도 셸 변수에 담을 수 없으므로 임의의 파일명 스트림을 변수 하나로 캡처하지 마.
산술 명령도 종료 상태를 만들어
(( expression ))은 계산 결과가 0이면 상태 1, 0이 아니면 상태 0을 돌려줘. 따라서 set -e 아래의 ((i++))는 i가 0일 때 스크립트를 멈출 수 있어. 값만 필요한지, 조건으로 쓸 것인지 구분해서 $((...))와 ((...))를 골라.