Skip to content
isdnetworks
Go back

힌트가 된 이미 깔린 목록

(수정됨)

한 서버에서만 스크립트가 실패했는데 무엇이 없어서 그런지를 알 수 없었다. 오류 메시지는 syntax error 라고만 하는데 다른 서버에서는 같은 스크립트가 잘 돌고 있었다.

Table of contents

Open Table of contents

원인 — 셸부터 갈린 환경

먼저 두 서버의 echo $SHELL 과 sh --version 을 나란히 찍어서 비교했다. 한쪽은 bash 이고 다른 쪽은 경량 배포판의 기본 셸 ash 였다.

스크립트에 [[ ]] 같은 bash 문법을 썼는데 한쪽에는 bash 자체가 없어서 난 오류였다. 셸만 다른 것이 아닐 수 있으므로 나머지 환경도 같이 비교하기로 했다.

해결 — 차집합이 뽑아 준 목록

두 서버의 ls /usr/bin /bin 목록을 각각 받아 sort 한 뒤 comm -23 으로 차집합을 냈더니 한쪽에 없는 명령 넷이 한 번에 나왔다. comm(1) 매뉴얼대로 -2 와 -3 을 주면 둘째 파일에만 있는 줄과 양쪽에 있는 줄이 빠지고 첫 파일에만 있는 줄이 남는다.

하나씩 실행해 보며 없는 것을 찾는 것보다 훨씬 빨랐다. apt list 와 apk info 로 패키지 목록도 비교해 봤는데 배포판이 달라 조회 명령도 형식도 달랐고 패키지 이름 자체가 배포판마다 다르므로 명령 이름으로 비교하는 쪽이 맞았다.

조치 — 스크립트가 하는 사전 확인

그 뒤로는 필요한 명령이 있는지를 스크립트가 시작 시점에 command -v 로 확인하게 했다. 없으면 무엇이 없는지를 이름으로 말하고 거기서 종료한다.

문법 오류보다 훨씬 나은 메시지이고 실패 지점이 실행 도중이 아니라 시작 시점으로 당겨지는 것도 이점이었다.

판단 기준 — 요구를 줄이는 쪽과 요구하는 쪽

두 가지 방법이 있었는데 스크립트를 POSIX sh 문법으로 전부 다시 쓰는 것과 간단한 것만 기본 도구로 바꾸고 나머지는 bash 를 요구하는 것이다. 뒤쪽을 골랐다. 이유는 복잡한 것을 억지로 기본 도구로 짜면 읽기 어려워져서다. 대신 경량 배포판 서버에 bash 를 하나 더 깔아야 하는 것을 감수했다.

간단한 것은 없이 하고 복잡한 것은 필요한 도구를 요구하는 쪽으로 갈랐다. 컨테이너에서 도는 것은 아예 Dockerfile 에서 이미지에 넣어서 서버마다 다를 일이 없게 했고 이미지 크기가 는 만큼 안 겪는 문제가 있었다.

주의 — 목록만으로는 부족한 판 차이

어느 서버에 무엇이 있는지를 TOOLS.md 표로 적어 두니 스크립트를 쓸 때 무엇을 쓸 수 있는지 알 수 있었다. 그런데 목록에 있어도 안 되는 경우가 나왔다.

같은 find 가 양쪽에 다 있는데도 판이 달라서 옵션 하나가 옛 판에는 없었다. --help 출력에서 그 옵션을 grep 으로 찾아 있으면 쓰고 없으면 빼는 형태로 바꿔서 넘어갔다. 있고 없고만이 아니라 판도 봐야 했고 목록에는 둘 다 있었다.

정리


Share this post on:

Previous Post
소요 시간이 유일한 신호다
Next Post
고치기 전의 실패 로그