iBetter Books
수정

셔뱅과 스크립트 구조

PART 01에서 hello.sh를 만들 때 첫 줄에 #!/bin/bash를 썼습니다. 그냥 관례라서 쓴다고 넘겼는데, 이제 그 줄이 정확히 무슨 역할을 하는지 알아볼 차례입니다.

셔뱅이란

셔뱅(Shebang)은 스크립트 파일의 첫 줄에 오는 특별한 주석입니다. #!(샵과 느낌표)로 시작해서 사용할 인터프리터의 경로를 적습니다.

#!/bin/bash

운영체제는 실행 파일을 열 때 첫 두 바이트를 확인합니다. #!가 보이면 "이 파일은 스크립트다. 뒤에 적힌 프로그램으로 실행하라"는 신호로 받아들입니다. 즉, #!/bin/bash가 있으면 /bin/bash가 해당 스크립트를 해석해서 실행합니다.

셔뱅이 없으면 어떻게 될까요? 현재 로그인 쉘이 실행을 맡습니다. zsh를 사용하는 환경에서 bash 전용 문법이 있는 스크립트를 실행하면 오류가 발생할 수 있습니다. 셔뱅은 "이 스크립트는 이 인터프리터로 실행해야 한다"는 명시적인 선언입니다.

#!/bin/bash vs #!/usr/bin/env bash

셔뱅을 쓰는 방법은 두 가지가 있습니다.

#!/bin/bash
#!/usr/bin/env bash

차이는 bash의 위치를 어떻게 찾느냐입니다.

#!/bin/bash/bin/bash에 bash가 있다고 가정합니다. 대부분의 리눅스 시스템에서는 맞지만, macOS에서 Homebrew로 설치한 최신 bash는 /usr/local/bin/bash/opt/homebrew/bin/bash에 있습니다. 이 경우 /bin/bash는 오래된 버전(3.x)이 실행됩니다.

#!/usr/bin/env bashenv 명령어에게 PATH에서 bash를 찾아달라고 부탁합니다. PATH에 등록된 bash를 실행하므로, Homebrew bash 같은 사용자 설치 버전을 올바르게 찾습니다.

구분 #!/bin/bash #!/usr/bin/env bash
bash 탐색 방식 절대 경로 고정 PATH에서 검색
이식성 낮음 (경로 다르면 실패) 높음 (다양한 환경 대응)
권장 환경 리눅스 단일 환경 다양한 OS 배포 예정 스크립트

이 교재에서는 Ubuntu 24.04 환경을 기준으로 하므로 #!/bin/bash를 사용합니다. 하지만 다른 사람과 공유할 스크립트를 만든다면 #!/usr/bin/env bash가 더 안전합니다.

스크립트의 기본 구조

잘 작성된 Bash 스크립트는 다음 순서를 따릅니다.

#!/bin/bash# 새 파일: scripts/greet.sh# =============================================================================# greet.sh - 사용자 정보를 출력하는 인사 스크립트# 작성자: ibetter# 작성일: 2026-04-24# =============================================================================# 변수 선언readonly GREETING="안녕하세요"user_name=$(whoami)current_dir=$(pwd)# 메인 로직echo "${GREETING}, ${user_name}님!"echo "현재 디렉토리: ${current_dir}"echo "현재 시각: $(date '+%Y-%m-%d %H:%M:%S')"# 종료exit 0

각 구역의 역할을 정리하면 다음과 같습니다.

  1. 셔뱅 — 인터프리터 선언. 반드시 첫 줄에 위치해야 합니다.
  2. 파일 설명 주석 — 스크립트의 목적, 작성자, 날짜를 기록합니다. 몇 달 뒤에 자신이 봐도 알아볼 수 있어야 합니다.
  3. 변수 선언 — 스크립트 전체에서 사용할 변수를 모아둡니다. 나중에 값을 바꿀 때 찾기 쉽습니다.
  4. 메인 로직 — 실제 작업을 수행하는 코드입니다.
  5. 종료exit 명령어로 종료 코드를 반환합니다.

exit 명령어와 종료 코드

스크립트가 끝나면 종료 코드(exit code)를 반환합니다. 0이면 성공, 0이 아니면 실패입니다. 이 규칙은 리눅스 전체에서 일관되게 지켜집니다.

exit 0    # 성공exit 1    # 일반 오류exit 2    # 잘못된 사용법 (인자 오류 등)

직전에 실행한 명령어의 종료 코드는 $?라는 특수 변수에 저장됩니다.

#!/bin/bash# 새 파일: scripts/exit_demo.shls /tmpecho "ls 종료 코드: $?"    # 성공이면 0ls /존재하지않는디렉토리echo "ls 종료 코드: $?"    # 실패이면 2exit 0

실행 결과는 다음과 같습니다.

$ bash scripts/exit_demo.sh
ls: cannot access '/존재하지않는디렉토리': No such file or directory
ls 종료 코드: 0
ls 종료 코드: 2

$?는 반드시 해당 명령어 바로 다음에 확인해야 합니다. 다른 명령어가 실행되면 그 값으로 덮어써집니다. 조건문과 함께 쓰면 더욱 유용한데, 이는 PART 04에서 자세히 다룹니다.

exit를 명시하지 않으면 마지막 명령어의 종료 코드가 스크립트의 종료 코드가 됩니다. 명확한 의사 전달을 위해 exit 0을 명시하는 것이 좋은 습관입니다.