launchd에서 node 못 찾는 문제, fnm default alias로 해결
터미널에선 되는데 launchd·cron에선 node를 못 찾는 이유와, fnm default alias로 PATH를 고정해 무인 스크립트 5개를 고친 과정을 정리했어요.
터미널에서는 잘 돌던 스크립트가 launchd에 올리면 조용히 죽는 경험, 혹시 있으신가요? 저는 어제 그 원인 하나를 잡아서 무인 실행 스크립트 5개를 한꺼번에 손봤어요.
증상: node: command not found
라이프케어로그는 플랜씨(plan-c)·플랜엘(plan-l) 같은 작은 도구를 혼자 만드는 브랜드라, 손이 안 가는 자동화가 꽤 많아요. 블로그 초안 생성, 이미지 큐 처리, 야간 리뷰, 릴리스 노트 정리 같은 셸 스크립트를 launchd가 정해진 시각에 돌려요.
이 스크립트들은 안에서 node를 불러요. 터미널에선 멀쩡하던 명령이 무인 경로에선 node: command not found로 끝나요. 이런 실패는 따로 알림이 없으면 알아채기 어렵다는 게 더 곤란한 점이에요.
원인: 셸 프로필을 안 읽는다
fnm은 eval "$(fnm env)" 한 줄을 셸 설정 파일에 넣어 두고, 셸이 뜰 때마다 현재 node 버전 경로를 PATH에 붙여요. 대화형 터미널에선 이 줄이 매번 실행되니 문제가 없죠.
launchd는 셸 설정 파일을 읽지 않아요. 직접 env를 찍어 보면 PATH에 기본 디렉토리 4개(/usr/bin, /bin, /usr/sbin, /sbin)만 들어 있어요. fnm이 붙여 주던 경로가 통째로 빠지니 node를 찾을 방법이 없어요.
대화형 터미널(프로필 실행, fnm 경로 포함) vs launchd(프로필 미실행, 기본 PATH 4개뿐)
선택: 버전 대신 alias를 가리키기
처음엔 스크립트마다 node 실행 파일의 절대 경로를 박을까 했어요. 그런데 fnm으로 node 버전을 올리는 순간 그 경로가 깨져요. 스크립트 5개를 매번 따라 고치는 건 반복이 늘어나는 방향이라 접었어요.
대신 fnm의 default alias를 썼어요. fnm default <버전>을 실행하면 fnm 디렉토리 아래 aliases/default에 그 버전이 연결돼요. 이 안의 bin을 PATH 맨 앞에 붙이면 버전을 바꿔도 alias만 따라오니 스크립트는 건드릴 일이 없어요.
적용: 스크립트 상단 한 줄
적용해 봤더니 각 스크립트 맨 위에 PATH 한 줄을 넣는 게 전부였어요. 커밋 하나에 파일 5개가 바뀌었고 로직은 그대로예요.
# launchd does not source the shell profile; pin node via fnm's default alias
FNM_ALIAS_BIN="$HOME/<fnm-dir>/aliases/default/bin" # check with: fnm env
export PATH="$FNM_ALIAS_BIN:$PATH"fnm 디렉토리 위치는 OS마다 달라서, 터미널에서 fnm env를 한 번 찍어 FNM_DIR 값을 확인하고 넣는 편이 안전해요.
확인은 launchd로 직접 한 번 돌려 보는 게 제일 확실해요. 잡을 즉시 실행해 로그에 node --version 결과가 찍히는지 보면 돼요. 버전 지정, 한 줄 추가, 실행 확인까지 3단계면 끝나요.
배운 것
- 무인 경로는 대화형 셸과 다른 환경이에요. "터미널에서 됐다"는 launchd에서 됐다는 증거가 아니에요.
- 버전 관리자를 쓸 땐 절대 경로 대신 alias를 가리키면 업그레이드 때 반복이 줄어요.
- 실패가 조용한 자동화엔 성공 로그 한 줄이라도 남겨 두는 게 좋아요.
무인 스크립트를 직접 만들어 보니, 혼자 운영하면서 제일 무서운 건 요란한 에러가 아니라 조용히 멈춘 자동화더라고요. launchd나 cron에 올린 스크립트가 있다면 오늘 env 한 번만 찍어 보세요.
관련 글
댓글
아직 댓글이 없어요. 첫 댓글을 남겨주세요.