"터미널은 그냥 터미널 아닌가?"에서 시작하지만, 스크립트가 "내 PC에선 됐는데 서버에선 안 돼요"에서 막힙니다. 셸은 명령을 해석하는 프로그램이고, 어떤 셸이 그 스크립트를 읽느냐에 따라 같은 코드가 다르게 동작합니다.
핵심 차이: 표준이냐 편의냐
sh는 POSIX 표준 셸의 이름입니다. 기능은 적지만 어디서나 거의 똑같이 동작해 이식성이 강점입니다. bash는 그 sh를 확장한 셸로, 배열·[[ ]] 조건문 같은 편의 기능을 더했고 대부분의 리눅스 기본 셸입니다. zsh는 bash와 비슷하지만 더 강력한 자동완성·테마(예: oh-my-zsh)로 대화형 사용 경험을 끌어올린 셸입니다.
| 구분 | sh | bash | zsh |
|---|---|---|---|
| 위치 | POSIX 표준 셸 | sh 확장 | bash와 유사·확장 |
| 강점 | 이식성 | 표준 기능·범용 | 자동완성·커스터마이징 |
배열·[[ ]] | 제한적 | 지원 | 지원 |
| 대표 환경 | 컨테이너·init 스크립트 | 대부분의 리눅스 | macOS 기본·개발자 선호 |
| 스크립트 첫 줄 | #!/bin/sh | #!/bin/bash | #!/bin/zsh |
언제 무엇을 쓰나
- 어디서나 돌아야 하는 스크립트 → sh: 알파인 컨테이너, 최소 설치 서버, init 스크립트. bash가 없을 수도 있는 환경입니다.
- 일반적인 자동화 스크립트 → bash: 배열·함수·
[[ ]]를 마음껏 쓰되 대부분의 리눅스에서 동작. - 매일 쓰는 대화형 셸 → zsh: 똑똑한 자동완성과 플러그인으로 작업 효율을 높이고 싶을 때.
흔한 함정이 하나 있습니다. #!/bin/sh로 시작하는 스크립트에 bash 전용 문법(배열, [[ ]])을 쓰면, 많은 시스템에서 /bin/sh가 dash 같은 가벼운 셸로 연결돼 있어 [[: not found 같은 오류가 납니다. bash 기능을 쓴다면 첫 줄을 #!/bin/bash로 정확히 명시해야 합니다.
직접 확인하기
지금 내가 어떤 셸을 쓰고 있는지, 그 셸이 어디 있는지 한 줄로 봅니다.
로컬 터미널
echo $0 # 현재 셸 이름
echo $SHELL # 로그인 기본 셸
cat /etc/shells # 설치된 셸 목록
OUTPUT
-bash
/bin/bash
/bin/sh
/bin/bash
/usr/bin/zsh
$0은 지금 실행 중인 셸, $SHELL은 로그인 기본 셸이라 둘이 다를 수 있습니다. 시스템에 설치된 셸 전부는 /etc/shells에서, 기본 셸 변경은 chsh -s /usr/bin/zsh로 합니다.
요점 정리
- sh = POSIX 표준·이식성, bash = sh 확장·리눅스 범용, zsh = 대화형 편의 강화.
- 셸이 다르면 같은 스크립트도 다르게 동작 — 특히 배열·
[[ ]]. - 스크립트는 쓰는 기능에 맞는 셔뱅(
#!/bin/shvs#!/bin/bash)을 정확히 명시. echo $0·$SHELL·/etc/shells로 내 셸 환경을 확인하세요.
셸별 문법 차이와 이식성 있는 스크립트 작성을 직접 실습하는 과정은 리눅스 트랙에서 회원가입 없이 무료로 익힐 수 있습니다.