Heredoc: 내장된 다중 줄 문자열
cat <<EOF
Hello, $USER
Today is $(date +%Y-%m-%d)
EOF여는 토큰 (여기 EOF)과 닫는 토큰 사이가 명령의 stdin. 기본값으로 변수 + 명령 치환 펼침.
확장 비활성: 구분자 인용
cat <<'EOF'
$USER stays literal
$(date) stays literal
EOF여는 구분자의 어떤 글자든 인용 (보통 전체 'EOF') 하면 변수 확장 OFF. 펼치면 안 되는 셸 풍 문법이 든 내장된 설정 / 스크립트 / 템플릿에 사용.
<<-로 탭 들여쓰기 정리하기
cat <<-EOF
hello
world
EOF<<-는 각 줄 앞의 탭만 제거하고 공백은 그대로 둬. heredoc을 블록 안에 들여쓸 때 편하지만, 에디터가 탭을 공백으로 바꾸면 기대한 정리가 일어나지 않아.
스크립트 인자
$0: 스크립트 이름.$1 $2 ...: 위치 인자.$#: 인자 개수.$@: 전부. 항상 인용:"$@".$*: IFS로 합친: 보통 잘못.shift: $1 drop, 재번호.
getopts로 플래그 파싱
verbose=0
while getopts ':vo:' opt; do
case "$opt" in
v) verbose=1 ;;
o) output="$OPTARG" ;;
\?) echo "bad flag: -$OPTARG" >&2; exit 2 ;;
esac
done
shift $((OPTIND - 1))POSIX getopts는 짧은 옵션을 다루는 작은 인터페이스에 잘 맞아. 긴 옵션, 하위 명령, 타입 검증이 늘어나면 손으로 파서를 키우기보다 argparse 같은 전용 도구로 옮기는 편이 오류 메시지와 테스트까지 단순해져.
인자를 전달할 때는 "$@"
"$@"는 받은 인자 각각을 그대로 한 인자로 보존해. 래퍼 스크립트가 하위 명령에 옵션과 파일명을 넘길 때 가장 중요한 형태야. 인용하지 않은 $@나 $*는 공백과 글로브를 다시 해석해 원래 경계를 잃을 수 있어.
공백은 지우지 않는 <<-의 경계
대시가 붙은 형식은 heredoc 본문을 탭 문자로 들여쓸 수 있게 해 주지만 공백은 지우지 않아. 눈에 보이지 않는 들여쓰기 문자가 실행 환경에 따라 바뀌지 않도록 의도적으로 선택해.
heredoc은 안전한 템플릿 엔진이 아니야
인용하지 않은 구분자는 셸이 stdin을 만드는 동안 변수, 명령, 산술 확장을 실행해. 원문 데이터라면 구분자를 인용하고, 치환 규칙이 복잡해지면 실제 템플릿 도구나 구조화 직렬화 도구를 사용해.