
배포 스크립트나 CI 파이프라인 때문에 어쩔 수 없이 Bash를 쓰는 분들, 이런 경험 있으실 거예요. 따옴표 하나 빼먹었더니 공백 있는 파일명에서 스크립트가 터지고, 중간 명령이 실패했는데도 조용히 다음 줄을 실행해버려서 사고가 커지는 경험이요. Bash는 어디에나 깔려 있어서 버릴 수는 없는데, 언어 자체는 함정투성이거든요. Amber라는 프로젝트는 이 문제를 '컴파일'이라는 방식으로 풀어요.
Amber가 뭐냐면요
Amber는 Rust로 만들어진 컴파일러예요. 현대적인 문법으로 코드를 작성하면, 컴파일 결과물로 순수한 Bash 스크립트가 나옵니다. TypeScript를 컴파일하면 JavaScript가 나오는 것과 똑같은 구도라고 생각하시면 돼요. 결과물은 별도의 런타임이나 의존성 없이 셸만 있으면 돌아가고요. 게다가 최신 릴리스부터는 Bash뿐 아니라 Ksh93과 Zsh 출력도 실험적으로 지원하기 시작했어요.
뭐가 좋아지냐면요
첫째, 타입 안전성이에요. Bash에서는 모든 값이 그냥 문자열인데요, Amber에는 Text, Num, Bool, Null 같은 타입과 [Text], [Num] 같은 배열 타입이 있고, 타입이 안 맞으면 실행하기 전 컴파일 시점에 에러로 잡아줘요. 숫자인 줄 알았던 변수가 빈 문자열이어서 한밤중에 배포가 깨지는 일을 미리 막아주는 거죠.
둘째, 에러 처리예요. Bash 최악의 함정이 '명령이 실패해도 계속 진행'인데, Amber는 실패할 수 있는(failable) 명령과 함수라는 개념이 언어에 박혀 있어요. 실패 가능성이 있는 호출은 failed 블록으로 직접 처리하거나 ? 연산자로 위로 전파해야 하고, 아무것도 안 하면 아예 컴파일이 안 됩니다. 에러를 '깜빡할' 수 없게 만든 거예요.
셋째, 문법이 요즘 언어답습니다. let으로 변수를 선언하고, fun으로 매개변수와 반환값에 타입을 지정한 함수를 만들고, if/else를 표현식으로 쓰고, loop로 배열과 범위를 순회해요. "Hello {name}!" 같은 문자열 보간도 되고요. 기존 셸 명령이 필요하면 $ ... $ 문법으로 감싸서 그대로 넣을 수 있는데, 이렇게 넣은 명령은 기본적으로 실패 가능한 것으로 취급돼서 에러 처리를 강제해요. 문자열 split/join/replace, 배열 헬퍼, 파일 조작, HTTP 다운로드 같은 표준 라이브러리도 있고, 이것들 전부 이식성 있는 셸 코드로 컴파일됩니다.
실용적인 디테일도 챙겼어요. 생성되는 스크립트는 Bash 3.2 이상에서 동작하는데요, macOS에 기본 탑재된 bash가 아직도 3.2 버전이라 이게 생각보다 중요하거든요. 컴파일러가 따옴표 처리와 에러 체크가 꼼꼼하게 들어간 방어적인 Bash를 대신 짜준다고 보시면 돼요.
비슷한 시도들과 비교하면요
셸 스크립트의 고통을 해결하려는 시도는 여러 갈래가 있었어요. ShellCheck는 잘못 쓴 Bash를 지적해주는 린터(코드 검사 도구)인데, 어디까지나 Bash를 직접 짜는 걸 도와주는 수준이죠. Nushell이나 Oil처럼 아예 새로운 셸을 만드는 진영도 있지만, 서버마다 새 셸을 설치해야 한다는 벽이 있어요. Python으로 도망가는 방법도 있지만 파이썬 버전과 의존성 관리라는 다른 지옥이 기다리고요. Amber의 포지션은 명확해요. 작성은 현대적인 언어로, 배포는 어디에나 있는 셸 스크립트로. 컴파일 결과물만 저장소에 넣으면 CI 서버든 운영 서버든 아무것도 설치할 필요가 없다는 게 핵심 차별점이에요. 현재 상태는 베타이고, GPL-3.0 오픈소스라 코드도 볼 수 있고, brew로 설치되고, 웹 플레이그라운드에서 바로 체험해볼 수도 있어요.
한국 개발자에게는요
CI/CD 스크립트, 배포 자동화, dotfiles 관리처럼 '어쩔 수 없이 Bash를 쓰던' 영역에서 바로 시도해볼 만해요. 특히 셸 스크립트가 수백 줄로 불어나서 유지보수가 무서워진 팀이라면 후보로 검토할 가치가 있어요. 다만 아직 베타라는 점은 감안하셔야 해요. 중요한 프로덕션 스크립트라면 컴파일 결과물을 한 번 눈으로 확인하는 습관이 필요하고, 생성된 Bash를 읽고 디버깅할 수 있는 사람도 팀에 여전히 있어야 하고요. 스크립트가 단순하다면 ShellCheck만으로 충분할 수도 있어요.
한줄 정리: 타입 검사와 에러 처리 강제가 있는 언어로 짜고, 어디서나 돌아가는 Bash로 배포한다 — 셸 스크립트의 TypeScript 같은 존재예요. 여러분 팀은 셸 스크립트가 몇 줄을 넘어가면 다른 언어로 갈아타시나요? 기준이 궁금해요!
🔗 출처: Hacker News