---
title: "터미널에서 오래 걸리는 명령이 끝나면 알림 받기"
description: "40분짜리 빌드를 지켜보고 있지 마세요. 어떤 명령 뒤에든 한 줄만 붙이면 결과가 휴대폰으로 옵니다. 이미 자리를 떴어도요."
date: 2026-09-09
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - 터미널
  - 셸
  - 빌드 알림
  - AI 코딩 에이전트
  - 웹훅 알림
---

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

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

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

## 그 한 줄

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

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

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

## 종료 코드도 같이 보내기

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

```bash
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`에 넣으세요.

```bash
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하는 것입니다. 그다음엔 이렇게.

```bash
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** — 세션 안에서 시작하고 분리하세요.

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

**nohup** — 일회성이라면.

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

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

## AI 코딩 에이전트

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

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

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

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

## 알림에 넣지 말아야 할 것

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

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

## 자주 묻는 질문

### `terminal-notifier`나 `notify-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 다운로드](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-notify-when-terminal-command-finishes-ko&mt=8) 또는 [Google Play에서 받기](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid) 후, 자리를 뜰 만큼 오래 걸리는 것에 한 번 걸어 보세요.

---

## 관련 문서

- [에이전트의 승인 대기를 전화로 바꾸기](/ko/blog/ai-agent-human-in-the-loop-alerts)
- [GitHub Actions 실패를 놓치지 않기](/ko/blog/github-actions-notifications)
- [cron 작업 실패 알림](/ko/blog/cron-job-failure-alerts)
- [Webhook 트리거 문서](/ko/docs/webhook)
- [채널 조건 참조](/ko/docs/conditions)
