본문 바로가기
C.W.K.
Stream
Lesson 02 of 12 · published

변수와 인용

~13 min · variables, quoting, expansion

Level 0창 구경꾼
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

세 가지 인용 방식

  • 'single'은 내용을 글자 그대로 보존하며 변수와 명령 치환을 확장하지 않아.
  • "double"은 변수와 명령 치환을 확장하면서도 결과를 인자 하나로 보존해. \$\"처럼 필요한 글자는 이스케이프할 수 있어.
  • 따옴표가 없으면 셸이 결과를 단어로 나누고 글로브까지 확장해. 일부러 그 동작이 필요한 경우가 아니라면 피해야 해.

먼저 한 값의 인자 경계를 지켜

name="Alice Lee"
echo $name           # Alice Lee  (겉보기와 달리 인자 두 개)
echo "$name"         # Alice Lee  (인자 하나)
for f in $files; do  # $files 값을 공백 기준으로 다시 나눔
for f in "$files"; do # 값 전체를 인자 하나로 전달

인용하지 않은 확장은 공백과 글로브 문자 때문에 인자 경계를 바꿔. 파일명이나 사용자 입력처럼 한 값이어야 하는 변수는 "$var"로 넘겨. 여러 값을 보관하려면 공백으로 이어 붙인 문자열이 아니라 배열을 쓰고 "${arr[@]}"로 펼치는 게 맞아.

기본값

: "${PORT:=8000}"     # 설정되지 않았거나 비어 있으면 할당
echo "${USER:-anon}"   # 설정되지 않았거나 비어 있으면 'anon'. USER 자체는 안 바뀜
: "${REQUIRED:?must be set}"  # 설정되지 않았거나 비어 있으면 오류 후 종료

앞의 :는 아무 일도 하지 않는 명령: 확장의 부수 효과만 원할 때. 매개변수 확장의 전체 표는 epilogue 트랙에서 다뤄.

사용자 입력 받기

read -rp 'Name: ' name
echo "hi $name"
# -r은 백슬래시를 글자 그대로 보존
# -s는 입력을 화면에 표시하지 않음(비밀번호 등)

로컬 변수와 전역 변수

bash와 zsh 함수에서는 local var=value로 함수 안의 이름을 따로 묶을 수 있어. 생략하면 호출한 쪽의 같은 변수를 덮어쓸 수 있어. 다만 local은 POSIX sh의 표준 문법이 아니므로, #!/bin/sh 스크립트라면 기대하면 안 돼.

여러 값은 배열로 경계를 보존해

name="Project Alpha"
echo $name             # 단어 분리 뒤 인자 두 개
echo "$name"           # 인자 한 개
for f in $files; do    # 문자열 하나를 다시 분리
for f in "$files"; do  # 항상 한 번만 반복

인용하지 않은 확장은 공백과 글로브 문자 때문에 인자 경계를 바꿔. 파일명과 사용자 입력처럼 한 값인 변수는 "$var"로 넘겨. 여러 값은 배열에 저장하고 "${arr[@]}"로 펼쳐.

인용은 인자 설계야

셸은 텍스트를 명령과 인자 목록으로 바꿔. 따옴표는 어디까지를 인자 하나로 보낼지 정해. 디버깅할 때는 printf '<%s>\n' "$@"처럼 실제 인자 경계를 출력해.

빈 값도 의미가 있어

인용한 빈 변수는 빈 인자 하나가 되지만, 인용하지 않은 빈 변수는 사라질 수 있어. 프로그램은 ‘옵션 값이 비어 있음’과 ‘옵션 자체가 없음’을 다르게 처리할 수 있으므로 인용은 공백뿐 아니라 빈 값의 의미도 지켜 줘.

Code

무조건 인용·bash
#!/usr/bin/env bash
set -euo pipefail
files=("a file.txt" "b.txt")
for f in "${files[@]}"; do
  ls -l -- "$f"
done

External links

Exercise

with space.txt 파일을 만든 뒤 f='with space.txt'를 설정해. 먼저 인용하지 않은 cat $f가 파일명을 둘로 나누는지 보고, cat "$f"로 한 인자를 보존하는 차이를 확인해. 마지막으로 ShellCheck를 기존 스크립트 하나에 돌려 봐.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.