4P by GN⁺ | ★ favorite | 댓글 1개
  • 이 위키는 단순히 긴 스크립트가 아니라, 손으로 작성되고 자료구조와 알고리듬까지 활용하는 “실질적인” Shell 프로그램을 모은 목록임
  • 기준은 대체로 5K 라인 이상이며, 자동 생성 스크립트나 반복적인 completion 스크립트는 핵심 사례에서 제외됨
  • 대표 사례는 ble.sh 87K 라인, kalua 약 56K SLoC/라인, Relax-and-Recover 35K 라인, nb 26K 라인, winetricks 22K 라인처럼 일반적인 Shell 스크립트 인식을 크게 넘어섬
  • 목록에는 대화형 라인 에디터, OpenWRT 애드온, Bash 디버거, TLS 테스트 도구, Kubernetes 구현, 백업·복구 도구, 인증서 발급 도구, 리소스 모니터 등 실사용 도구가 폭넓게 포함됨
  • OSH “Wild” 테스트는 백만 라인 이상의 Shell을 파싱하지만, 대부분은 작은 프로그램과 반복적인 배포판 패키지 정의라 대형 Shell 프로그램과 구분됨

무엇을 “큰 Shell 프로그램”으로 보는가

  • 여기서 “biggest”는 단순한 원시 라인 수보다 “substantial”, 즉 실질적인 규모와 복잡도를 뜻함
  • 포함 대상은 기본적으로 손으로 작성된 Shell 스크립트
    • autoconf가 생성한 큰 스크립트는 예외로 둠
    • 70K 라인의 coreutils 스크립트 같은 자동 생성물은 실질적인 의미의 대형 Shell 프로그램으로 보지 않음
  • 자료구조와 알고리듬을 쓰는 Shell 프로그램을 특히 중시함
    • bash-completion은 정교하지만, Unix 머신의 각 명령마다 비교적 단순한 함수를 두는 반복적 구조라 반례에 가까움
  • 대략적인 기준선은 5K 라인 초과
    • 반복적이지 않은 가장 큰 Shell 프로그램은 대체로 10K+ 라인 범위에 있음
    • 100K 라인을 넘는 프로그램은 확인하지 못한 상태임

가장 큰 Shell 프로그램 사례

  • akinomyoga/ble.sh: 총 87K 라인, 주석 제외 63K LoC
    • 순수 bash로 작성된 fish 같은 대화형 라인 에디터임
    • 메인 파일 out/ble.sh는 39K 라인, 주석 제외 29K LoC이며, 모듈 파일까지 합치면 총 80K+ 라인임
    • 일본어 주석이 많음
    • bind -x로 터미널의 raw bytes를 읽고, 여러 명시적 상태 머신으로 직접 디코딩하며, drawing buffer를 유지·갱신함
    • timing과 “fibers”도 포함함
    • Shell parser 관련 상세 내용은 issue 663 댓글에 있으며, Shell에서 자료구조를 가장 정교하게 쓴 사례 중 하나로 평가됨
    • OSH에서 실행하려는 시도가 있고 대부분 파싱됨
    • 첫 커밋은 2015년에 8K 라인 / 6K LoC였으며, 실제 개발은 2013년에 시작됨
  • kalua: OpenWRT 애드온으로, 약 56K SLoC/라인의 POSIX shell로 작성됨
  • Relax-and-Recover: 35K 라인, 24K LoC의 백업·복구 도구임
    • 첫 git 커밋은 2009년 3월이며 당시 4K 라인 / 3K LoC였음
  • xwmx/nb: nb 자체가 26K 라인, 22K LoC의 bash로 작성됨
    • bats 테스트를 bash로 계산하면 추가로 91K 라인, 61K LoC가 있음
    • 첫 커밋은 2014년이고, 활발한 커밋 이력은 2016년 초부터 시작됨
  • vegardit/bash-funk: 총 27K 라인, 24K LoC의 Bash 라이브러리임
    • 첫 커밋은 2017년 5월이며 당시 10K 라인 / 8K LoC였음
  • winetricks: 22K 라인의 Shell 스크립트이며 Wine 아래에 여러 Windows 프로그램을 설치함
  • drwetter/testssl.sh: 단일 파일에 21K 라인의 bash가 들어 있음
    • 손으로 작성된 것으로 보임
    • 2006년에 몇 개의 openssl 명령으로 시작함
    • 파싱 중 issue #606에 걸림
  • rkhunter: 2003년부터 2018년까지 작성된 21K 라인의 Bourne shell 프로그램임
  • Simplenetes: “Kubernetes in 17K lines of Shell”로 소개됨
    • 놀라운 사례로 표시되어 있지만 dormant 상태로 보임
    • 관련 Hacker News Thread가 연결됨
  • inxi 2.3.56: obsolete로 표시된 16K 라인의 bash 프로그램임
    • 2008년에 infobash에서 fork됨
    • 당시 infobash는 889 라인이었고, infobash는 2005년에 시작됨
    • v2.9부터 inxi는 Perl 구현으로 대체됨
  • bashdb: Bash 디버거이며 약 14K 라인의 bash로 작성됨
  • romkatv/powerlevel10k: internal/ 디렉터리에 12K 라인의 zsh 스크립트가 있음
    • 추가로 config와 helper script가 8K 라인 있음
    • 첫 커밋은 2014년임
  • dylanaraps/neofetch: Bash 3.2로 작성된 10K 라인 프로그램이며 시스템 정보를 표시함
    • 이미지와 관련된 흥미로운 기능도 할 수 있음
    • 첫 커밋은 2015년임
  • distrobox: 7K 라인 이상의 bash 스크립트로, 터미널 안에서 어떤 Linux 배포판이든 사용할 수 있게 함
  • acme.sh: 8K 라인의 Shell 스크립트이며 인증서를 발급하고 갱신함

규모는 작아도 눈에 띄는 구현

  • bashforth: 약 3,800 라인으로 아주 크지는 않지만 실제 프로그래밍 언어를 구현함
    • 공백과 주석이 많음
  • yoda: bashforth의 절반 정도 크기지만 인터프리터와 컴파일러 전체를 구현함
    • 같은 작성자의 20년 더 젊은 구현으로, 더 많은 기능을 담고 있음
    • “What learned you have, unlearn you must!”라는 코멘트가 붙어 있음

그 밖의 주요 Shell 프로그램

  • abcde / A Better CD Encoder: CD ripping에 쓰이며 약 5.5K LoC
  • thc-segfault: 3.3K LoC이며 대부분 Bash로 만든 pubnix 서버임
  • ffmpeg/configure: FFmpeg의 손으로 작성된 configure 스크립트이며 8.4K LoC
  • ffhevc: FFmpeg와 libx265로 HEVC 비디오를 인코딩하는 완전 수작성 Bash wrapper이며 4K LoC
  • ffx264: FFmpeg와 libx264로 H.264/AVC 비디오를 인코딩하는 완전 수작성 Bash wrapper이며 3.9K LoC
  • h264enc: MEncoder로 H.264/AVC 비디오를 인코딩하는 완전 수작성 Bash wrapper이며 9.2K LoC
  • bashtop: 5.3K LoC의 리소스 모니터임
  • halcyon: Haskell 앱 설치 시스템이며 6.6K LoC
    • bash semantics와 오류 검사에 주의를 기울인 수작성 코드이며, 함수형 프로그래밍에서 영감을 받은 독특한 스타일임
  • wordshell: 약 7K 라인의 코드로, 명령줄에서 여러 WordPress 사이트를 관리함
  • BaCon: 약 10K 라인이며 BASIC으로 작성된 프로그램을 C로 변환함
    • BASIC 구현과 Shell 스크립트 구현 두 가지가 있음
  • FireHOL: 메인 스크립트가 9K 라인, FireQOS 도구가 추가로 3K 라인임
    • 사람이 읽기 쉬운 설정에서 secure, stateful firewall을 만드는 언어이자 실행 프로그램임
  • gxadmin: 11K LoC이며 과학 워크플로 엔진 Galaxy 관리를 위한 templated SQL query와 데이터 처리 유틸리티 모음임
  • mulle-bashfunctions: 약 6K 라인의 bash/zsh용 함수 라이브러리임
    • mulle-sde에서 사용되며, mulle-sde는 또 다른 100K 라인의 Shell 스크립트임
  • x11docker: 11.6K 라인이며 docker 또는 podman 컨테이너에서 GUI 애플리케이션을 실행함

Shell 유사 언어와 DSL

  • modernish: Shell로 작성된 portable shell dialect임
  • bats: 테스트 작성을 위한 DSL이며 bash 코드를 생성함
  • bashible: bash로 작성된 Ansible 유사 DSL임
  • clash: 모든 현대적 POSIX shell과 호환되는 객체지향 프레임워크임
  • bash Infinity: bash용 표준 라이브러리와 boilerplate 프레임워크임

더 작은 프로그램과 관련 생태계

  • Alpine, Aboriginal, Debian 스크립트는 별도 blog post로 연결됨
  • completion 스크립트는 크지만 종종 반복적
    • _git Zsh completion은 8.3K 라인의 코드임
    • git-completion.bash와 Docker completion도 예로 듦
  • dyne/Tomb: 약 3,500 라인의 zsh 스크립트임
  • Basalt: 순수 Bash로 작성된 full-featured package manager임
    • 몇천 라인 규모지만, 15개 이상의 앱과 라이브러리를 포함한 rich ecosystem이 있음
    • bash-core: trapshopt builtin을 확장하고 stacktrace와 필수 편의 기능을 추가하는 라이브러리임
    • bash-object: 순수 Bash로 임의 중첩 자료구조를 구성하는 라이브러리이며 테스트가 거의 200개 있음
    • bash-json: 순수 Bash로 JSON을 파싱하고 출력하는 라이브러리임
  • tablespoon/fun/cli-clock: bash로 작성된 여러 줄 문자 시계임
  • json.bash / jb: JSON을 만드는 명령줄 도구이자 bash 라이브러리임
    • 1,700 라인이며 테스트가 약 3,000 라인 있음

OSH 테스트와 Shell 사용상의 주의점

  • OSH "Wild" Tests는 백만 라인 이상의 Shell을 파싱함
    • 대부분은 작은 프로그램과 Alpine PKGBUILD, Gentoo ebuild 같은 반복적인 배포판 패키지 정의임
  • Shell Programs That Run Under OSH는 OSH에서 실행되는 Shell 프로그램 목록으로 연결됨
  • shell script are dangerous는 Shell이 시스템 내부를 대화형 콘솔 또는 비대화형으로 다루는 프로그램이며, 기능이 많고 매우 위험하고 애플리케이션 제작용으로 만들어진 것이 아니라고 경고함

댓글과 토론

Hacker News 의견들
  • 약 25년 전 Sony에서 일할 때, 매우 느리고 자주 죽던 주문 관리 시스템을 고치는 프로젝트를 맡았음
    파고들어 보니 OMS는 AIX 서버에서 돌아가는 거대한 셸 스크립트 묶음이었고, 10년 넘게 진화하다 방치된 상태였음. 코드가 5만 줄이 넘었고, 주문·결제·기타 정보는 FTP로 서버 간 이동한 뒤 복잡한 sed/awk로 파싱했으며, 재고도 텍스트 파일로 추적하면서 FTP로 옮기고 있었음
    당시에는 Perl이 이 난장판을 옮기기에 가장 실용적으로 보였고, 가장 단순한 부분부터 작은 Perl 모듈로 바꾸며 더 큰 Perl 애플리케이션 안에서 단계적으로 리팩터링했음. 3개월 만에 전체를 약 5천 줄의 Perl로 줄였고, 원래 시스템의 장애는 거의 사라진 채 10~100배 빨라졌음. 끔찍했지만 지금까지 한 일 중 가장 만족스러운 작업 중 하나였음
    • 겨우 3개월이라니, 매일 800줄씩 삭제한 셈임
      원래 코드를 다 읽고 깊이 이해한 뒤 동작을 정확히 맞춘 건지, 아니면 큰 덩어리는 버리고 “이렇게 동작해야 한다”고 생각한 대로 새로 쓴 건지 궁금함. 빠르게 대체 가능한 상용구가 많았던 건지도 궁금함
    • 그런 셸 스크립트 괴물을 완화하는 데는 지금도 Perl이 가장 실용적임. Tcl도 좋은 선택지임
  • 예전에 쓴 것들을 다시 뒤져봐야겠음
    처음 쓴 정말 큰 스크립트는 Enrust CA와 디렉터리용 약 7천 줄짜리 설치 프로그램이었고, 당시의 거의 모든 Unix에서 돌아가야 했음. 처음부터 그랬던 건 아니지만 고객 요구에 따라 커졌음
    설치 자체는 그리 복잡하지 않았지만 업그레이드는 좀 복잡했고, 당시에는 Unix마다 모든 유틸리티가 조금씩 달랐음. 스크립트 상당 부분은 그런 차이를 찾아내고 관리하는 코드였고, 오류 감지·복구·롤백, 아주 원시적인 패키지와 의존성 관리도 들어 있었음
    DEC의 Unix, Ultrix가 아닌 쪽이 가장 난해했음. 모든 명령줄 유틸리티가 출력물을 터미널 열 너비에서 잘라낸다는 걸 깨닫는 데 며칠 걸렸고, 30년이 지난 지금도 그게 기억남
    HP-UX는 릴리스마다 깨지는 변경이 있었고, 기억이 맞다면 6.5부터 11까지 지원했음. Ultrix, Novell 쪽, NeXT, Sequent는 거의 기억나지 않음. AIX는 이상했다는 건 기억나지만 이유는 잊었음. Sun의 세 가지/네 가지 OS도 차이가 있었지만, 매뉴얼은 훌륭했고 최고였음
    • 열 너비에서 잘리는 출력은 정말 이상하게 들림. 터미널에 가로 스크롤 같은 기능이 없었던 게 확실한지 궁금함
    • DEC의 Unix라면 OSF/1, Digital Unix, Tru64 Unix 중 어느 쪽을 말하는 건지 궁금함
    • 나도 수천 줄까지는 갔지만 대략 2천 줄 정도였음. 그래도 지원해야 한 건 최신 Red Hat과 Ubuntu뿐이어서 다행이었음
    • 작년에 한 프로젝트의 주 바이너리와 보조 라이브러리에 wc를 돌려보니 지금까지 6,224줄
      입력 프로토콜 어댑터, 하나 이상의 필터, 출력 프로토콜 어댑터로 된 컨테이너 묶음으로 선형 보장 파이프라인을 관리하는 스크립트였음. 컨테이너나 프로토콜 전문가가 아니더라도 파일이 파이프라인을 지나며 어떻게 필터링·변환되길 원하는지 아는 사람들이 쓸 수 있게 만드는 것이 목표였음
      최상위 바이너리는 git [ git options ] < git action> [action options]systemctl처럼 하위 기능을 두는 구조임. 새 하위 명령을 추가하는 하위 명령도 있고, 필요한 라이브러리를 만들고 템플릿에서 함수 정의를 미리 채움. 템플릿에는 짧은/긴 사용법 함수가 있어 cbap -hcbap pipeline -h가 유용한 안내를 줌
      기본 이미지, 컴포넌트, 파이프라인을 조작하는 하위 명령들이 있음. 코드 상당 부분은 컴포넌트와 파이프라인 정의가 올바르게 작성됐는지 확인하는 테스트용임. 파이프라인은 거의 TOML에 가까운 형식이라 TOML 파싱, 섹션을 배열로 변환하는 코드가 있고, 컴포넌트는 단순한 key=value 파일이라 좌변·우변 추출과 스키마 검증 코드가 있음
      파이프라인 컴포넌트가 속성을 공유할 수 있어서 varetc 파일에서 공통 속성을 찾고 컴포넌트 속성을 지정하는 코드도 있음. 보안 요구사항에 맞춘 사용자·그룹·디렉터리·FIFO 조작 함수도 많음. 파이프라인을 설정하면 사용자, 그룹, SELinux 타입, MCS 카테고리를 생성·적용한 뒤 컴포넌트를 시작하는 서비스 파일에 매핑하므로 systemd 조작도 많음
      가장 큰 호출 묶음은 아마 컴포넌트 속성, 실제로는 컨테이너 속성을 가져오고 설정하는 함수들임. 각 속성마다 가져오기 함수, 검증 함수, 파이프라인 내 인라인 버전을 둬서 데이터 기반 컨테이너 정의를 최대한 유연하게 만들었음
      파일, 환경 변수, 명령줄에서 변수를 설정하기 위해 Bash 참조를 많이 쓰는 코드도 있어 빠른 테스트가 가능함. 사용자 수준도 코드 자체를 다루는 유지관리자, 컴포넌트 정의를 개발하는 개발자, 컴포넌트로 파이프라인을 만드는 통합자, 파이프라인을 설치하는 운영자까지 네 단계로 지원하며, 각 수준 사용자에게 내보내기 위해 자기 자신을 복사·패키징할 수 있음
      대상 시스템이 어떤 Linux든 될 수 있으므로 makeself로 패키징하고 추출함. 예를 들어 통합자가 파이프라인 정의를 만들면 makeself 파일이 생성되고, 대상 시스템에서 실행 시 모든 사용자·그룹·디렉터리·FIFO, 즉 컴포넌트 간 IPC를 만들고 DAC/MAC을 적용하며 systemd 파일을 만들고 각 사용자에게 이미지를 복사한 뒤 파이프라인을 실행함. 삭제 옵션으로 이 모든 것을 되돌릴 수도 있음
      seccomp도 일부 들어 있지만, 허용 목록과 차단 목록 사이의 균형을 찾아야 해서 잠시 멈춘 상태임. ShellCheck는 정말 철저히 사용함
  • 내 스크립트 언어 Lil의 인터프리터를 이식성을 최대화하려고 Bash로 작성할까 고민한 적이 있지만, 부동소수점 연산이 극도로 고통스러울 거라는 걸 금방 깨달았음
    모든 환경에 bc/dc가 있다고 기대할 수도 없고, 보유한 일부 머신은 Bash 버전이 오래되어 연관 배열 지원도 매우 제한적이었음. 타협안으로 AWK를 대상으로 삼았는데, AWK는 대부분의 셸보다 훨씬 쾌적한 범용 언어이고 POSIX 환경이면 어디에나 있음: https://beyondloom.com/blog/lila.html
    • 나도 언어를 셸 대상으로 만들다가 bc/dc를 모든 환경에 기대할 수 없다는 걸 직접 알게 됨
      WSL2의 Ubuntu 설치에 bc/dc가 없었던 것 같아 꽤 놀랐음. 부동소수점 계산은 AWK를 쓰고 있지만, 그냥 외부 프로세스로 호출하는 방식임
  • 경력 중 여러 번 큰 Perl 프로그램을 작성하고 유지보수해 본 입장에서, 사람들이 이렇게 하는 데는 이유가 있음
    Java나 Python 같은 언어는 인터페이스와 형식이 정의되어 있고 OS 상호작용이 거의 없을 때 잘 맞음. JSON/XML/YAML을 쓰거나 데이터베이스, 다른 프로그램과 HTTP(S)로 통신하는 식이면 이런 언어가 빛나는 이상적인 상황이 만들어짐
    하지만 대량의 텍스트와 OS 상호작용을 다루면 Java와 Python은 큰 고통이 됨. 반대로 Shell/Perl은 이런 작업에서 훨씬 수월하다는 걸 느끼게 됨
    거의 모든 자동화 작업, 혼란스럽고 표준화되지 않은 인터페이스, 텍스트/로그 파일, 구조화되지 않았거나 충분히 구조화되지 않은 데이터 형식이 여기에 해당함. 여기에 Perl의 하위 호환성, 넓은 설치 기반, 성능까지 더하면 이런 작업에는 Perl 말고 대안이 사실상 없음
    요즘 대기업들이 사소하게 자동화 가능한 일을 하려고 수천 명을 고용하는 수작업 노동이 많은 큰 이유 중 하나는 Perl 사용이 줄었기 때문이라고 오래전부터 봐왔음. Python이나 Java로 큰 자동화 작업을 해보려다가, 작성·유지해야 할 코드의 장황함과 전체 규모에 질려 곧 포기하게 됨
    • “Perl이 사라져서 그렇다”는 데는 강하게 동의하지 않음. 복잡도가 올라갔고, 스크립트를 이어 붙이던 Perl 담당자의 일이 전업이 되었으며 Perl만으로도 한계가 있었던 것에 가깝다고 봄
      그래서 이제는 아마 비싼 정규직 인력이 추가로 필요한 상태가 됨. 최종 사용자가 Windows라면 이미 데스크톱에 Perl 비슷한 선택지가 있음. PowerShell이고 Perl과 비슷한 역할을 함
    • 큰 자동화 작업을 네이티브 코드로 했음. 이런 경우에는 효율성이 중요하기 때문임
      Bash+grep은 텍스트 한 줄마다 새 프로세스를 실행하는 쪽으로 흐르기 쉬움. 효율적으로 하려면 작업을 최소화해야 하고, 그러려면 배치 처리와 중복 제거가 필요함. 이는 중복 제거 문맥을 추적하면서 상태 있는 방식으로 데이터를 다뤄야 한다는 뜻이고, 제대로 된 프로그래밍 언어에서 더 쉬움
      Bash+grep은 무상태 텍스트 처리에 유리해서 작업 중복이 커지기 쉽음. 작업을 줄이는 또 다른 방법은 정확한 필터링인데, 이는 제대로 된 언어에서 명령형으로 깔끔하게 표현하기가 더 쉬움. grep과 정규식은 이런 용도에는 전혀 맞지 않음
      줄 단위 형식을 쓰면 git이 무엇이든 수용하려고 이스케이프를 붙이는데, 지원이 일관되지 않고 -z 옵션으로 널 종료 문자열 형식을 요청해 비활성화할 수 있음. Bash가 이를 처리할 방법은 없는 것 같고, 충분히 저수준 언어에서는 자연스럽게 다룰 수 있음. 또한 텍스트 한 줄마다 새 프로세스를 시작하지 않아도 되는 점진적 스트리밍도 가능함
      덤으로 중간에 HTTP가 있든 다른 것이 있든 모든 작업에 단일 코드베이스를 쓸 수 있음
    • 동의함. 내가 가장 좋아하는 언어는 Python이지만, 특정 저수준 OS 작업에는 성가시거나 비효율적일 수 있음. 그래서 https://www.oilshell.org와 링크된 위키 페이지를 만들었음
      맥락을 위한 링크 몇 개가 있음. “Perl을 다시 발명하는 건가?”: https://www.oilshell.org/blog/2021/01/why-a-new-shell.html#a...
      “Unix 셸은 Perl 6/Raku 같은 빅뱅이 아니라, 호환 가능한 업그레이드 옵션을 둔 Perl 5처럼 진화해야 한다”: https://www.oilshell.org/blog/2020/07/blog-roadmap.html#the-...
      YSH 둘러보기: https://www.oilshell.org/release/latest/doc/ysh-tour.html
    • Perl이 많은 Linux와 BSD 시스템에 기본 설치되어 있다는 걸 깨달은 뒤로 Perl 5를 진지하게 배워볼까 고민 중임. OpenBSD에도 Perl이 설치되어 나오는 것으로 알고 있음
      인터넷에서 뭔가를 설치할 수 없거나 아예 인터넷에 닿을 수 없는 환경에서 일하기 전까지는 이게 큰 장점처럼 보이지 않을 수 있음
  • 큰 프로그램을 Bash 스크립트로 작성할 때의 핵심 문제는 셸 스크립트 언어가 애초에 복잡성을 위해 설계되지 않았다는 데 있음
    작은 명령을 조율하고 기존 도구를 빠르게 탐색적으로 이어 붙이는 데는 뛰어나지만, Bash가 몇백 줄을 넘어가기 시작하면 장기 유지보수와 확장성을 골치 아프게 만드는 한계가 연달아 나타남
    먼저 가독성이 문제임. Bash 문법은 커질수록 정말 난해해질 수 있음. 변수 범위 규칙은 미묘하고, 오류 처리는 원시적이며, 문자열 처리는 금방 지저분해짐. 결국 유지보수자가 무슨 일이 일어나는지 해독하느라 시간을 낭비하고, 자신 있게 변경하기도 어려워짐
    다음은 견고한 도구 부족임. 더 성숙한 언어에는 정적 분석 도구, 린터, 디버거가 있어 흔한 실수를 일찍 잡아줌. Bash에서는 이런 것들이 없거나 매우 제한적임. 이런 안전장치가 없으면 큰 Bash 프로그램은 조용한 오류, 회귀, 미묘한 버그에 더 취약함
    테스트도 문제임. Bash 스크립트를 테스트할 수는 있지만 과정이 보통 더 번거롭고, 복잡한 로직이나 자료 구조가 있으면 더 까다로워짐. 파일명 공백이나 예기치 못한 환경 조건 같은 경계 사례를 다루다 보면 검증하기 고통스러운 방어 코드가 잔뜩 생김
    마지막으로 생태계 자체가 대규모 Bash 개발을 위해 만들어져 있지 않음. 모듈화, 패키지 관리, 표준화된 의존성 처리, Python이나 Go가 제공하는 현대적 개발 패턴을 잃게 됨. 시간이 지나면 이런 결핍이 누적되어 속도를 늦춤
    일회성 작업이나 단순 자동화에 Bash를 쓰는 건 괜찮음. 그게 Bash가 잘하는 일임. 하지만 뭔가 큰 것을 만들 생각이라면 보통은 복잡한 애플리케이션을 만들고 유지보수하도록 설계된 언어를 쓰는 편이 낫고, 초기 학습 곡선이나 설정이 조금 더 높더라도 장기적으로 시간을 아껴줌
    • ShellCheck를 린터로 쓰면 흔한 함정을 많이 잡을 수 있음. Bash/셸에는 정말 많은 함정과 예상 밖 동작이 있어서 숙련된 Bash 작성자도 걸릴 수 있음
      다만 Bash/셸은 언어 위계에서 독특한 위치를 차지함. 거의 어디에나 있고 30년 뒤에도 남아 있을 가능성이 큼. 거의 어디서나 실행되고 30년 뒤에도 실행될 프로그램을 원한다면 셸/Bash는 좋은 선택임
    • 지금 직장에서 바로 이걸 겪는 중임. 수천 줄짜리 Bash를 파헤치고 있음
      오래전에 작성된 스크립트도 아닌데 왜 Bash를 골랐는지 모르겠음. 스크립트는 동작하지만, 코드를 잘못 쳐다보기만 해도 뭔가 깨질 것 같은 느낌임
    • Bash/ksh에는 디버깅·추적 인자로 -x가 있음
  • 예전에 정기적으로 썼던 가장 큰 수작업 셸 프로그램은 아마 abcde (A Better CD Encoder) 였고, 약 5,500줄 규모였음
    https://abcde.einval.com
    https://git.einval.com/cgi-bin/gitweb.cgi?p=abcde.git;a=blob...
    • 잘 안다고 하긴 그렇지만, 예전에 What.CD에서 추천하던 도구 중 하나였음. Max도 함께 추천됐다고 친구들이 말해줬음: https://github.com/sbooth/Max
    • 써본 적 있는데 정말 잘 동작했고 사용하기도 꽤 쉬웠음. 전체가 거대한 셸 스크립트인 줄은 전혀 몰랐음
  • 이런 프로그램 중 상당수는 진짜 보석임. 예를 들어 rkhunter 스크립트는 코드도 괜찮고 개선 여지도 있으며, 정보의 보고이기도 함
    이런 스크립트의 코드 크기 중 많은 부분은 여러 플랫폼에서 필요한 유틸리티가 존재하는지, 그리고 다양한 명령줄 옵션에서 기대대로 동작하는지를 보장하는 데 쓰임. 이게 진지한 셸 스크립트 작성자에게는 가장 고통스러운 지점이고, 신호와 하위 프로세스보다도 더 힘듦
    rkhunter가 “제대로 된” 프로그래밍 언어로 작성됐다면 이런 정보는 덜 투명했을 것 같음. 자료 구조 안의 레코드로 밀려 들어가 조회되거나, 중첩 자료 구조 위에서 여러 함수, 혹은 더 나쁘게는 메서드와 클래스 조합으로 동작했을 수 있음. 로그도 JSON으로 쪼개지고 데이터베이스에 압축되어 다른 메서드로 접근해야 했을지 모름
    셸 스크립트는 그런 복잡한 도구가 없기 때문에 오히려 무슨 일이 벌어지는지 그대로 드러내는 경향이 있음. 그래서 rkhunter는 여러 익스플로잇과 루트킷에 대한 괜찮은 문서 역할도 하며, 파일에서 파일로, 구조에서 구조로, 데이터베이스에서 데이터베이스로 파고들 필요가 적음
  • FreeBSD Update 클라이언트는 약 3,600줄의 sh 코드임
    여기서 언급된 다른 프로그램에 비하면 크지 않지만, “운영체제 전체를 업데이트하는 도구”라는 기능량은 꽤 묵직하다고 봄. 업데이트를 빌드하는 코드는 여러 파일에 나뉘어 있어서 합치면 더 많을 것임
  • “고작” 7.1천 줄이지만, 내가 좋아하는 건 Let’s Encrypt에서 인증서를 발급하고 갱신하는 데 쓰이는 acme.sh 스크립트임
    https://github.com/acmesh-official/acme.sh/blob/master/acme....
  • 때로는 사용 가능하다고 보장할 수 있는 게 셸뿐이고 이식성이 꼭 필요한 상황도 있음
    하지만 일반적으로 거대한 셸 애플리케이션이 있다면 인생의 선택을 다시 생각해봐야 할 수도 있음
    • 문제는 “어느 셸인가”임. Bash는 보편적인 것과 거리가 멂
      게다가 보통 셸만으로는 할 수 있는 일이 많지 않고 find, grep, sed, cat, head, tail, cut 같은 명령이 필요함. 이 명령들도 각자의 이식성 문제가 있음
      BusyBox를 대상으로 삼는 것이 최선일 수 있지만, 일반적인 Linux 시스템을 벗어나는 순간 이식 가능한 Bourne 셸 스크립트를 작성하는 일은 어렵거나 거의 불가능해짐
    • 이런 얘기를 꽤 자주 듣는데, 셸은 있지만 C 컴파일러가 없거나 셸을 통해 C 컴파일러를 설치할 수 없는 경우가 실제로 얼마나 되는지 진심으로 궁금함
      C 컴파일러만 있으면 셸에서 벗어나 C 프로그램을 작성해 셸 스크립트가 조합하게 하거나, Lua 같은 더 나은 스크립트 언어를 설치할 수 있음. 지금 시점에 반드시 셸만 써야 하는 경우는 꽤 틈새처럼 느껴짐