---
title: "Dostawaj powiadomienie, gdy długie polecenie w terminalu się skończy"
description: "Przestań pilnować czterdziestominutowego builda. Jedna linijka po dowolnym poleceniu wysyła wynik na telefon — także wtedy, gdy już odszedłeś."
date: 2026-09-09
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - terminal
  - powłoka
  - powiadomienia o buildzie
  - agenci kodujący AI
  - powiadomienia webhook
---

# Dostawaj powiadomienie, gdy długie polecenie w terminalu się skończy

Odpalasz trening, pełny zestaw testów, `docker build` albo agenta kodującego przy długim zadaniu. Zostają ci dwie złe opcje: siedzieć i patrzeć na pasek postępu, albo odejść i wrócić dwadzieścia minut później, żeby odkryć, że wywaliło się po dziewięćdziesięciu sekundach.

Jest trzecia opcja i mieści się w jednej linijce.

## Ta jedna linijka

Utwórz kanał w Echobell, skopiuj jego adres webhooka i dopisz to za tym, co uruchamiasz:

```bash
pnpm build; curl -sS -X POST https://hook.echobell.one/t/TWOJ_TOKEN \
  -H 'content-type: application/json' \
  -d '{"title":"build zakończony","body":"echobell-web"}'
```

Zwróć uwagę na `;`, a nie `&&`. Przy `&&` powiadomienie leci tylko wtedy, gdy polecenie się powiodło, a to jest dokładnie na odwrót — to o porażce chcesz wiedzieć najbardziej.

## Wyślij też kod wyjścia

Powiadomienie mówiące „zakończone" opowiada połowę historii. Przechwyć status:

```bash
pnpm build; s=$?; curl -sS -X POST https://hook.echobell.one/t/TWOJ_TOKEN \
  -H 'content-type: application/json' \
  -d "{\"title\":\"build $([ $s -eq 0 ] && echo ok || echo BLAD)\",\"status\":\"$s\"}"
```

`s=$?` musi być bezpośrednio po poleceniu — cokolwiek pomiędzy, łącznie z samym testem `[`, nadpisze `$?`.

## Zrób z tego funkcję powłoki

Wpisywanie tego za każdym razem niweczy sens. Wrzuć to do `~/.zshrc` albo `~/.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
}
```

Ustaw `ECHOBELL_HOOK` w profilu powłoki — a lepiej trzymaj go całkiem poza repozytorium dotfiles i eksportuj z pliku, którego nie commitujesz. Potem:

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

Końcowe `return $status` ma znaczenie: utrzymuje `notify` przezroczystym, więc `notify make && ./deploy.sh` nadal zachowuje się tak, jak się spodziewasz.

Z takim payloadem szablony kanału mogą wyglądać tak:

**Tytuł**

```
{{command}} · {{status}}
```

**Treść**

```
na {{host}}
```

## Dzwoń tylko, gdy się wywali

Większość uruchomień kończy się dobrze i nie musisz o nich słyszeć. Dwa kanały załatwiają to czysto: zwykły na wszystko i połączeniowy z warunkiem:

```
status != "0"
```

Skieruj `notify` na drugi kanał dla tego, dla czego wstałbyś z łóżka, a udane uruchomienia zostaną ciche.

## Przetrwać zamknięty laptop i zerwaną sesję SSH

Jeśli polecenie działa przez SSH, zamknięcie laptopa zabija powłokę i powiadomienie nigdy nie wychodzi. Dwa sposoby:

**tmux** — uruchom polecenie w sesji i odłącz się:

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

**nohup** — na jeden raz:

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

W obu przypadkach proces przeżywa twoje połączenie, a powiadomienie dociera niezależnie od tego, czy jesteś jeszcze podłączony.

## Agenci kodujący AI

Ten sam wzorzec obejmuje agenta CLI pracującego nad długim zadaniem:

```bash
notify codex exec "zrefaktoruj moduł płatności i uruchom testy"
```

Dla agentów, którzy zatrzymują się w połowie i czekają na człowieka — zgoda, prośba o uprawnienie — powiadomienie o zakończeniu jest złym narzędziem, bo uruchomienie się nie zakończyło. Ten przypadek potrzebuje własnego hooka albo callbacku agenta i zasługuje raczej na telefon niż na push. [Zamiana bramek zatwierdzania agenta w połączenia telefoniczne](/pl/blog/ai-agent-human-in-the-loop-alerts) omawia dokładnie to, łącznie z hookiem `Notification` w Claude Code i jego matcherem `agent_needs_input`.

Używaj obu: hooka do „utknąłem", funkcji powłoki do „skończyłem".

## Czego nie wkładać do powiadomienia

**Nie wyjścia polecenia.** Kusi, żeby wrzucić ostatnie linijki nieudanego builda do treści. Powstrzymaj się: logi buildów zawierają tokeny, ciągi połączeń i dane klientów częściej, niż się ludziom wydaje, a treść powiadomienia ląduje na zablokowanym ekranie. Wyślij kod wyjścia i idź spojrzeć w terminal.

**Nie adresu kanału do publicznego repozytorium dotfiles.** Każdy, kto ma ten adres, może pisać na twój kanał. Trzymaj go w pliku poza wersjonowaniem i włącz **Tylko POST**, żeby zabłąkany podgląd linku go nie wyzwolił.

## Najczęstsze pytania

### Czemu nie użyć `terminal-notifier` albo `notify-send`?

One pokazują powiadomienie na maszynie, która wykonuje polecenie. Działa to, dopóki przy niej siedzisz. Cały sens tej konfiguracji to przypadek, gdy nie siedzisz: zdalna maszyna, zamknięty laptop, inny pokój.

### Czy to działa na Windowsie?

Wzorzec tak, składnia inaczej. W PowerShellu odpowiednikiem jest `Invoke-RestMethod -Method Post -Uri $env:ECHOBELL_HOOK -ContentType application/json -Body $json`, a zamiast `$?` używa się `$LASTEXITCODE`.

### Czy dostanę powiadomienie na zegarek?

Tak. Subskrypcje docierają na sparowany Apple Watch, który szczerze mówiąc jest właściwym formatem dla „build się skończył".

### A jeśli polecenie trwa 12 godzin?

Nic tu nie wygasa — `curl` uruchamia się wtedy, gdy polecenie zwróci sterowanie. Odpal je pod tmuxem, żeby zerwane połączenie nie zabrało procesu ze sobą.

### Czy koledzy z zespołu mogą dostawać te same powiadomienia?

Mogą. Udostępnij kanał, a każdy subskrybent wybierze własny typ powiadomienia. Przydatne na współdzielonej maszynie treningowej, gdzie więcej niż jedna osoba czeka, aż GPU znów będzie wolne.

## Podsumowanie

Jedna funkcja powłoki, jeden kanał i warunek, jeśli chcesz tylko porażek. Konfiguracja zajmuje jakieś dwie minuty i oddaje ci te dwadzieścia, które spędzasz na gapieniu się w paski postępu.

[Pobierz Echobell na iPhone'a](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-notify-when-terminal-command-finishes-pl&mt=8) albo [weź go z Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid), a potem wypróbuj na czymś na tyle długim, żeby odejść.

---

## Powiązane treści

- [Zamiana bramek zatwierdzania agenta w połączenia](/pl/blog/ai-agent-human-in-the-loop-alerts)
- [Nie przegap awarii GitHub Actions](/pl/blog/github-actions-notifications)
- [Alerty o nieudanych zadaniach cron](/pl/blog/cron-job-failure-alerts)
- [Dokumentacja wyzwalacza webhook](/pl/docs/webhook)
- [Dokumentacja warunków kanału](/pl/docs/conditions)
