Interactive Shell vs Script Shell

macOS 터미널을 열면 zsh가 반긴다. Catalina(10.15, 2019)부터 기본 로그인 셸이 zsh로 바뀌었기 때문이다. 그런데 셸 스크립트를 열어보면 첫 줄은 대부분 이렇다:

#!/bin/bash

zsh가 기본인데 왜 스크립트는 bash를 쓸까? 핵심은 interactive shell과 script shell은 별개의 영역이라는 점이다.

macOS에서 이 둘은 이렇게 나뉜다:

구분역할
로그인/인터랙티브 셸zsh사용자가 터미널에서 직접 명령을 입력할 때
스크립트 실행 셸bash 또는 shshebang이 지정한 셸로 스크립트를 실행할 때

참고로 macOS의 /bin/sh는 실제로 bash 3.2가 POSIX 호환 모드로 동작하는 것이다.

Shebang이 #!/bin/bash인 이유

스크립트가 bash를 고집하는 데는 몇 가지 이유가 있다.

호환성이 우선이다

스크립트는 어떤 환경에서든 돌아가야 한다. bash는 거의 모든 Unix/Linux 시스템에 설치되어 있지만, zsh는 Linux에 기본 포함되지 않는 경우가 많다. #!/bin/zsh를 쓰면 zsh가 없는 환경에서 스크립트가 깨진다.

zsh는 인터랙티브에 특화되어 있다

zsh의 강점 - 탭 완성, 프롬프트 커스터마이징, 플러그인 시스템 등 - 은 사람이 직접 터미널을 조작할 때 빛나는 기능들이다. 스크립트 실행에는 이런 기능이 필요 없다.

역사적 관성

bash는 30년 넘게 Linux/macOS의 사실상 표준 스크립트 셸이었다. 기존 스크립트 생태계가 전부 bash 기준으로 작성되어 있으니, 굳이 다른 셸로 바꿀 이유가 없다.

POSIX 호환성 스펙트럼

이식성에 대한 요구 수준에 따라 shebang 선택이 달라진다:

  • 최대 이식성: #!/bin/sh - POSIX 표준만 사용
  • bash 확장 필요: #!/bin/bash - 배열, [[ ]], 프로세스 치환 등
  • zsh 전용: #!/bin/zsh - zsh 없는 환경에서 실행 불가

대부분의 스크립트는 bash 수준의 기능이면 충분하므로 #!/bin/bash가 실용적인 선택이 된다.

Apple은 왜 zsh로 바꿨나 - GPLv3 이야기

macOS가 기본 셸을 zsh로 바꾼 이유는 기술적 판단이 아니라 라이선스 문제다.

bash 3.2까지는 GPLv2 라이선스였다. Apple은 이를 문제없이 macOS에 탑재해왔다. 그런데 2009년 bash 4.0부터 라이선스가 GPLv3로 변경되었고, Apple은 GPLv3를 거부했다.

그 결과 Apple은 bash 3.2.57(GPLv2의 마지막 버전)에서 업데이트를 멈추고, 허용적(permissive) 라이선스를 가진 zsh를 기본 셸로 채택했다.

GPLv3의 무엇이 문제인가

GPLv3는 상업 사용을 금지하는 라이선스가 아니다. 자유 소프트웨어 라이선스다. 하지만 GPLv2에 없던 두 가지 조항이 Apple의 사업 모델과 정면으로 충돌한다.

Anti-Tivoization (Section 6)

GPLv3 소프트웨어를 탑재한 하드웨어는 사용자가 해당 소프트웨어를 수정하고 교체할 수 있도록 허용해야 한다. Apple의 폐쇄적 생태계 - 서명된 바이너리, 잠긴 부트로더, System Integrity Protection - 와 양립할 수 없는 조건이다.

Tivoization이란?

TiVo가 Linux(GPLv2)를 사용하면서도 하드웨어 잠금으로 사용자의 소프트웨어 수정을 막은 관행에서 유래한 용어다. GPLv3는 이를 명시적으로 금지한다.

Patent Retaliation (Section 10, 8)

GPLv3 코드에 대해 특허 침해 소송을 제기하면(Section 10), 라이선스가 자동으로 종료된다(Section 8). 대규모 특허 포트폴리오를 운용하는 Apple에게는 리스크 요인이다.

GPLv2와의 차이

GPLv2에는 이런 조항이 없었다. 소스 코드 공개 의무는 있지만, 하드웨어 수준의 수정 자유나 특허 관련 제약은 규정하지 않았다. Apple이 bash 3.2까지는 문제없이 탑재할 수 있었던 이유다.

정리

macOS에서 “기본 셸”과 “스크립트 셸”은 서로 다른 영역이다.

  • zsh는 사용자가 터미널에서 쓰는 인터랙티브 셸
  • bash는 스크립트 생태계의 사실상 표준
  • Apple이 zsh로 전환한 건 GPLv3 라이선스 회피가 목적이지, bash가 기술적으로 열등해서가 아니다

터미널을 열면 zsh의 세계, 스크립트를 실행하면 bash의 세계 - 둘은 공존하고 있다.