본문 바로가기
C.W.K.
Stream
Lesson 04 of 05 · published

서브셸과 명령 그룹화

~8 min · subshell, grouping, scope

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

명령을 묶는 두 방식

  • { cmd1; cmd2; }: 현재 셸에서 실행하므로 변수, 옵션과 디렉터리 변경이 뒤에도 남아.
  • (cmd1; cmd2): 별도 서브셸 환경에서 실행하므로 그 안의 셸 상태 변경이 부모 셸로 돌아오지 않아.

둘 다 여러 명령을 하나의 복합 명령으로 다룰 수 있지만 상태가 남는 범위가 달라. 외부 파일과 서비스에 만든 부수 효과는 서브셸을 썼다고 자동으로 되돌아가지 않아.

중괄호는 현재 셸에서 함께 처리해

여러 명령의 출력을 하나의 파일로 보낼 때 유용해.

{
  echo "=== build log ==="
  date
  ./build.sh
} > build.log 2>&1

블록 전체에 리디렉션이 한 번 적용돼. 현재 셸에서 실행되므로 블록 안의 cd와 변수 할당은 뒤 명령에도 영향을 줄 수 있어.

괄호는 셸 상태를 격리해

(
  cd ~/projects/temp || exit
  ./make.sh
)
# 부모 셸의 현재 디렉터리는 바뀌지 않아

작업 디렉터리나 셸 옵션을 잠깐 바꾸고 끝낼 때 편해. 다만 그 안에서 수정한 파일, 보낸 네트워크 요청과 시작한 외부 프로세스까지 취소되는 트랜잭션은 아니야.

명령 치환도 별도 실행 환경을 사용해

result=$(cmd)는 명령의 stdout을 값으로 캡처해. 명령 치환 안에서 바꾼 셸 변수와 현재 디렉터리는 부모 셸에 남지 않지만, stderr는 별도로 리디렉션하지 않으면 바깥으로 보일 수 있어. 큰 데이터나 NUL 바이트를 셸 변수에 담는 방식은 적합하지 않으므로 출력 형식과 크기를 확인해.

중괄호 문법에는 명령 경계가 필요해

{}는 예약어라 주변 공백이 필요하고, 닫는 중괄호 앞에는 세미콜론이나 줄바꿈으로 앞 명령을 끝내야 해. { cmd; }처럼 쓰면 돼. 괄호와 중괄호를 한 줄로 지나치게 압축하면 리디렉션 범위와 실패 지점을 읽기 어려워지므로 여러 단계는 블록 모양을 유지해.

서브셸은 실패 처리를 대신하지 않아

서브셸 안에서 첫 명령이 실패해도 다음 명령이 계속 실행될지는 &&, if, 셸 옵션과 명시적인 종료 처리에 달렸어. 디렉터리 변경이 부모에 남지 않는다는 사실과 작업 전체가 원자적으로 성공한다는 주장은 전혀 달라. 실패 뒤 남을 파일과 정리 절차도 따로 설계해야 해.

그룹의 상태는 마지막 명령만 보면 놓칠 수 있어

중괄호 그룹과 서브셸 그룹은 기본적으로 마지막에 실행한 명령의 종료 상태를 바깥에 돌려줘. 앞 단계가 실패하고 마지막 echo가 성공하면 그룹이 성공처럼 보일 수 있어. 여러 단계를 하나의 게이트로 사용할 때는 실패 시 즉시 0이 아닌 상태를 반환하게 만들고, 결과 파일은 모든 단계가 끝난 뒤에만 교체해.

Code

그룹 + 리다이렉트·bash
{
  echo '== status =='
  date
  uname -a
  df -h /
} > /tmp/snapshot.txt 2>&1
cat /tmp/snapshot.txt
서브셸 자동 복귀·bash
pwd
(
  cd /tmp
  pwd          # 현재 경로: /tmp
)
pwd            # 원래 경로로 돌아옴

External links

Exercise

서브셸 안에서 /tmp로 이동해 pwd를 출력한 뒤 바깥의 pwd가 원래 위치인지 확인해. 이어서 중괄호 그룹의 두 출력 줄을 파일 하나로 보내고 종료 상태를 확인해. 첫 명령을 일부러 실패시켜 마지막 명령 상태만 볼 때 무엇을 놓치는지도 비교해.

Progress

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

댓글 0

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

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