Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

Bash 셸의 탄생: 톰슨 셸에서 오픈소스까지

셸 스크립팅은 시스템 관리자 역할을 맡은 사람이라면 누구나 갖춰야 할 필수 역량입니다. 오늘날 스크립트를 작성하는 데 가장 널리 쓰이는 셸은 단연 Bash입니다. Bash는 거의 모든 리눅스 배포판과 최신 macOS에 기본 탑재되어 있으며, 곧 Windows Terminal에도 기본으로 포함될 예정입니다. 그야말로 Bash는 어디에나 있는 셈입니다.

그렇다면 Bash는 어떻게 이 지경에 이르게 되었을까요? 이번 주 Command Line Heroes 팟캐스트는 바로 이 질문을 코드를 직접 작성한 본인들에게 물으며 깊이 있게 파헤칩니다.

모든 것은 유닉스에서 시작되었다

프로그래밍 이야기라면 늘 그렇듯, 우리는 유닉스로 거슬러 올라가야 합니다. 셸의 역사를 잠깐 짚어보면, 1971년 켄 톰슨(Ken Thompson)이 최초의 유닉스 셸인 톰슨 셸(Thompson Shell)을 공개했습니다. 하지만 이 셸에는 사용자가 스크립팅을 할 수 있는 범위에 심각한 제약이 있었습니다. 이는 곧 자동화의 한계로 이어졌고, 나아가 IT 운영 분야 전체의 발전을 가로막는 장애물이 되었습니다.

훌륭한 연구 자료 하나가 초기 스크립팅 시도의 어려움을 잘 보여줍니다(명령어는 굵게 표시).

Multics의 전임 셸과 마찬가지로 이 셸(/bin/sh)은 커널 외부에서 실행되는 독립적인 사용자 프로그램이었습니다. 글로빙(globbing, *.txt처럼 매개변수 확장을 위한 패턴 매칭)과 같은 개념은 별도의 유틸리티인 glob에서 구현되었고, 조건식을 평가하는 if 명령 역시 마찬가지였습니다. 이러한 분리 덕분에 셸은 C 소스 900줄 미만의 작은 크기를 유지할 수 있었습니다.

이 셸은 현대 셸까지 살아남은 리디렉션(< >, >>)과 파이핑(| 또는 ^)을 위한 간결한 문법을 도입했습니다. 순차 명령 실행(;)과 비동기 명령 실행(&) 지원도 이미 갖추고 있었습니다.

톰슨 셸에 없던 것은 바로 스크립팅 능력이었습니다. 그 셸의 유일한 목적은 명령을 호출하고 결과를 확인하기 위한 대화형 셸(명령 인터프리터)이었을 뿐입니다.

터미널 접근성이 높아지면서 자동화에 대한 관심도 함께 커져갔습니다.

한 걸음 더 나아간 본 셸

톰슨의 첫 셸 공개 6년 후인 1977년, 스티븐 본(Stephen Bourne)이 톰슨 셸의 스크립팅 한계를 해결하고자 본 셸(Bourne Shell)을 발표했습니다(1990년부터 Bash의 주요 유지보수자를 맡아온 첫 레이미(Chet Ramey)가 Command Line Heroes 에피소드에서 이에 대해 이야기합니다). 벨 연구소가 유닉스 시스템의 일부로 내놓은 기술의 자연스러운 진화였습니다.

그렇다면 본은 무엇을 다르게 하려 했을까요? 연구자 M. Jones가 이를 잘 정리해 줍니다.

본 셸에는 두 가지 주요 목표가 있었습니다. 운영체제를 위해 명령을 대화형으로 실행하는 명령 인터프리터 역할과, 셸을 통해 호출할 수 있는 재사용 가능한 스크립트를 작성하는 스크립팅 역할입니다. 톰슨 셸을 대체하는 것 외에도 본 셸은 이전 셸들에 비해 여러 장점을 제공했습니다. 본은 제어 흐름, 반복문, 변수를 스크립트에 도입해 운영체제와 상호작용하는(대화형 및 비대화형 모두) 더 완성도 높은 언어를 제공했습니다. 또한 셸 스크립트를 필터로 사용할 수 있게 하고 신호(signal) 처리를 위한 통합 지원을 갖췄지만, 함수 정의 기능은 없었습니다. 마지막으로 백쿼트(back quote)를 이용한 명령 치환이나, 스크립트 안에 문자열 리터럴을 그대로 삽입하는 HERE 문서처럼 오늘날에도 쓰이는 여러 기능들을 포함했습니다.

본은 과거 인터뷰에서 이렇게 설명한 바 있습니다.

원조 셸은 사실 언어가 아니었습니다. 그것은 일종의 녹음이었죠. 파일에 담긴 명령들을 선형으로 실행하는 방식일 뿐, 유일한 제어 흐름 원시문은 GOTO 라벨이었습니다. 켄 톰슨이 작성한 원조 셸의 이런 한계는 상당히 컸습니다. 예컨대 명령 스크립트를 필터로 손쉽게 활용할 수 없었습니다. 명령 파일 자체가 표준 입력이 되어버렸기 때문입니다. 그런데 필터에서 표준 입력은 부모 프로세스로부터 상속받는 것이지 명령 파일이 아닙니다.

원조 셸은 단순했지만, 사람들이 유닉스를 애플리케이션 개발과 스크립팅에 활용하기 시작하면서 너무 제한적이라는 게 드러났습니다. 변수도 없었고, 제어 흐름도 없었으며, 따옴표 처리 능력도 크게 부족했습니다.

새로운 셸은 스크립트 작성자들에게 엄청난 진전이었지만, 그것에 접근할 수 있어야만 의미가 있었습니다.

본 셸을 자유 소프트웨어로 다시 탄생시키다

그때까지 주류 셸들은 벨 연구소가 소유하고 운영하는 독점 소프트웨어였습니다. 운이 좋다면 대학을 통해 유닉스 셸에 접근할 수 있겠지만, 그런 제한된 접근성은 자유 소프트웨어 재단(FSF)이 꿈꾸던 세상과는 거리가 멀었습니다.

리처드 스톨만(Richard Stallman)과 뜻을 같이하는 개발자들은 GNU 라이선스 아래 자유롭게 사용할 수 있도록 유닉스의 모든 기능을 새로 구현하는 작업에 착수했습니다. 그중 한 개발자에게 셸 만들기 임무가 주어졌는데, 그 개발자가 바로 브라이언 폭스(Brian Fox)입니다. 그가 자신의 임무를 이야기하는 방식은 참으로 흥미롭습니다. 그는 팟캐스트에서 이렇게 말합니다.

이 일이 그토록 어려웠던 이유는 본 셸의 모든 동작을 충실히 모방하면서도, 동시에 확장을 허용해 사람들이 쓰기에 더 좋은 도구로 만들어야 했기 때문입니다.

당시는 또한 셸 표준이 무엇인지 논의되던 시기이기도 했습니다. 이런 역사를 배경으로, 경쟁을 앞세워 인기 있던 본 셸은 새롭게 재탄생합니다.

'다시 태어난(Bourne-Again)' 셸

자유 소프트웨어라는 사명과 경쟁이라는 두 가지 촉매제가 '본 어게인 셸(Bourne-Again Shell)', 즉 Bash를 탄생시켰습니다. 당시로서는 드문 선택이었지만, 폭스는 자신의 이름을 딴 대신 유닉스에서 자유 소프트웨어로의 진화를 담은 이름을 붙였습니다(폭스 셸(Fox Shell)이었다면 Fish 셸보다 먼저 fsh 명령을 차지했을 텐데 말이죠 #놓친기회). 이 이름 선택은 그의 성격과도 닮아 있습니다. 폭스는 에피소드에서 개인적인 영광의 이미지조차 관심이 없었으며, 프로그래밍 문화의 진화에 기여하려 했다고 말합니다. 다만 좋은 언어유희 정도는 놓치지 않았습니다.

본 본인이 이 말장난에 서운해하지 않았다는 점도 다행스러운 일이었습니다. 본은 컨퍼런스에서 누군가 다가와 Bash 티셔츠를 건네준 일화를 소개하는데, 그 사람이 바로 브라이언 폭스였다고 합니다.

출시 연도 개발자
톰슨 셸 1971년 켄 톰슨
본 셸 1977년 스티븐 본
본 어게인 셸(Bash) 1989년 브라이언 폭스

시간이 흐르면서 Bash는 점차 널리 채택되었습니다. 다른 엔지니어들이 사용하기 시작하고 설계 개선 사항을 제출하기 시작했습니다. 실제로 수년 후 폭스는 Bash에 대한 통제권을 내려놓는 법을 배운 것이 자신의 인생에서 가장 중요한 일 중 하나였다고 강조했습니다. 유닉스가 리눅스와 오픈소스 소프트웨어 운동에 자리를 내주면서, Bash는 오픈소스 세계의 핵심 스크립팅 동력이 되었습니다. 위대한 프로젝트는 한 사람의 비전을 넘어 성장하는 법입니다.

셸에서 배울 수 있는 것들

셸은 노트북을 쓰는 일상과 너무나 밀접하게 연결된 기술이라, 그것조차 발명이 필요했다는 사실을 잊기 쉽습니다. 톰슨에서 본으로, 그리고 Bash로 이어진 이 이야기에서 우리는 낯익은 교훈을 얻을 수 있습니다.

  • 올바른 사명을 품은 개인은 놀라운 성과를 이룰 수 있습니다.
  • 오늘날 우리가 의존하는 많은 것들이 아직 현역인 업계 전설들의 작업 위에 세워져 있습니다.
  • 살아남는 소프트웨어는 원래 창조자의 비전을 넘어 진화하는 소프트웨어입니다.

Command Line Heroes는 시즌 3 내내 프로그래밍 언어를 다루며 이제 막바지에 이르렀습니다. 구독하고 프로그래밍 언어의 기원에 대한 모든 것을 확인해 보세요. 여러분의 셸 이야기를 댓글로 들려주신다면 더없이 기쁠 것입니다.