터미널에서 오래 걸리는 명령이 끝나면 알림 받기

40분짜리 빌드를 지켜보고 있지 마세요. 어떤 명령 뒤에든 한 줄만 붙이면 결과가 휴대폰으로 옵니다. 이미 자리를 떴어도요.

업데이트

목차

학습을 돌리거나, 전체 테스트를 실행하거나, docker build를 걸거나, AI 코딩 에이전트에게 긴 작업을 맡깁니다. 그다음 남는 선택지는 둘 다 별로입니다. 앉아서 진행 막대를 보고 있거나, 자리를 떴다가 20분 뒤에 돌아와 사실 90초 만에 실패했다는 걸 알게 되거나.

세 번째 선택지가 있고, 한 줄이면 됩니다.

그 한 줄

Echobell에서 채널을 만들고 webhook URL을 복사한 뒤, 실행하려는 것 뒤에 이걸 붙이세요.

pnpm build; curl -sS -X POST https://hook.echobell.one/t/YOUR_TOKEN \
  -H 'content-type: application/json' \
  -d '{"title":"빌드 종료","body":"echobell-web"}'

&&가 아니라 ;라는 점에 주의하세요. &&를 쓰면 명령이 성공했을 때만 알림이 갑니다. 그건 정확히 반대입니다. 실패야말로 가장 알고 싶은 경우니까요.

종료 코드도 같이 보내기

"끝났습니다"만 말하는 알림은 절반짜리입니다. 상태도 잡으세요.

pnpm build; s=$?; curl -sS -X POST https://hook.echobell.one/t/YOUR_TOKEN \
  -H 'content-type: application/json' \
  -d "{\"title\":\"빌드 $([ $s -eq 0 ] && echo 성공 || echo 실패)\",\"status\":\"$s\"}"

s=$?는 반드시 명령 바로 다음에 와야 합니다. 사이에 뭔가 끼면 [ 테스트 자체를 포함해 $?를 덮어씁니다.

셸 함수로 만들기

매번 저걸 치면 취지가 사라집니다. ~/.zshrc~/.bashrc에 넣으세요.

notify() {
  "$@"
  local status=$?
  curl -sS -X POST "$ECHOBELL_HOOK" \
    -H 'content-type: application/json' \
    -d "{\"command\":\"$*\",\"status\":\"$status\",\"host\":\"$(hostname -s)\"}" \
    >/dev/null
  return $status
}

ECHOBELL_HOOK은 셸 프로필에서 설정하세요. 더 좋은 방법은 dotfiles 저장소에 아예 넣지 않고, 커밋하지 않는 파일에서 export하는 것입니다. 그다음엔 이렇게.

notify pnpm test
notify cargo build --release
notify python train.py

마지막의 return $status가 중요합니다. notify를 투명하게 유지해 주기 때문에 notify make && ./deploy.sh도 기대한 대로 동작합니다.

이 페이로드라면 채널 템플릿은 이렇게 쓸 수 있습니다.

제목

{{command}} · {{status}}

본문

{{host}}에서

실패했을 때만 울려 주세요

대부분의 실행은 성공하고, 그건 들을 필요가 없습니다. 채널 두 개면 깔끔하게 해결됩니다. 전부 받는 일반 채널 하나와, 조건을 건 전화 채널 하나.

status != "0"

침대에서 일어날 만한 것만 두 번째 채널로 보내면, 성공한 실행은 조용히 지나갑니다.

노트북을 닫아도, SSH가 끊겨도 살아남기

명령이 SSH 위에서 돌고 있다면 노트북을 닫는 순간 셸이 죽고 알림은 영영 나가지 않습니다. 두 가지 해법:

tmux — 세션 안에서 시작하고 분리하세요.

tmux new -d -s build 'notify pnpm build'

nohup — 일회성이라면.

nohup bash -c 'notify pnpm build' >/dev/null 2>&1 &

어느 쪽이든 프로세스가 연결보다 오래 살아남고, 접속 중이든 아니든 알림은 도착합니다.

AI 코딩 에이전트

같은 방식이 긴 작업을 처리 중인 CLI 에이전트에도 그대로 적용됩니다.

notify codex exec "결제 모듈을 리팩터링하고 테스트를 돌려줘"

작업 도중 멈춰 사람을 기다리는 에이전트 — 승인, 권한 요청 — 에게는 완료 알림이 잘못된 도구입니다. 아직 완료되지 않았으니까요. 그 경우엔 에이전트 자체의 훅이나 콜백이 필요하고, 푸시보다 전화가 어울립니다. 에이전트의 승인 대기를 전화로 바꾸기가 바로 그 이야기이고, Claude Code의 Notification 훅과 agent_needs_input matcher도 다룹니다.

둘 다 쓰세요. 훅은 "막혔다", 셸 함수는 "끝냈다".

알림에 넣지 말아야 할 것

명령 출력. 실패한 빌드의 마지막 몇 줄을 본문에 넣고 싶어지지만 참으세요. 빌드 로그에는 토큰, 접속 문자열, 고객 데이터가 사람들 생각보다 자주 들어 있고, 알림 본문은 결국 잠금 화면에 뜹니다. 종료 코드만 보내고 터미널은 직접 가서 보세요.

채널 URL을 공개 dotfiles 저장소에. URL을 가진 사람은 누구나 당신의 채널로 보낼 수 있습니다. 버전 관리하지 않는 파일에 두고 POST만 허용을 켜서, 떠도는 링크 미리보기가 발동시키지 못하게 하세요.

자주 묻는 질문

terminal-notifiernotify-send를 쓰면 안 되나요?

그건 명령을 실행하는 기계에 알림을 띄웁니다. 그 앞에 앉아 있는 동안엔 잘 작동하죠. 이 구성의 요점은 앉아 있지 않은 경우입니다. 원격 머신, 닫힌 노트북, 다른 방.

Windows에서도 되나요?

방식은 같고 문법이 다릅니다. PowerShell에서는 Invoke-RestMethod -Method Post -Uri $env:ECHOBELL_HOOK -ContentType application/json -Body $json이 대응되고, $? 대신 $LASTEXITCODE를 씁니다.

시계로도 받을 수 있나요?

받을 수 있습니다. 구독은 페어링된 Apple Watch로 전달되고, "빌드 끝났다"에는 솔직히 그게 가장 맞는 형태입니다.

명령이 12시간 걸리면요?

이 구성에는 타임아웃이 없습니다. 명령이 반환하는 그 시점에 curl이 실행될 뿐입니다. 연결이 끊겨도 프로세스가 딸려가지 않도록 tmux 아래에서 돌리세요.

동료도 같은 알림을 받을 수 있나요?

가능합니다. 채널을 공유하면 구독자마다 알림 유형을 고릅니다. GPU가 다시 비었는지를 여러 사람이 신경 쓰는 공용 학습 머신에서 특히 유용합니다.

마무리

셸 함수 하나, 채널 하나, 실패만 받고 싶다면 조건 하나. 설정에 2분쯤 걸리고, 진행 막대를 보며 쓰던 20분을 돌려줍니다.

iPhone용 Echobell 다운로드 또는 Google Play에서 받기 후, 자리를 뜰 만큼 오래 걸리는 것에 한 번 걸어 보세요.


관련 문서