본문으로 건너뛰기
cccskills
무료GitHub에 공개

witr

Explain which process holds a port or file lock, what started it, and what keeps it running. Uses the witr CLI to trace services, containers, and parent processes without stopping or changing anything.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Explains why a process is running and what started it, using the witr CLI. Use when a port is already in use (EADDRINUSE), a dev server or other process was left running, an unknown or stuck process needs explaining, or you need to know which service, container, shell, supervisor or scheduled job started a process, holds a port or holds a file lock. Use it instead of chaining lsof, ps, ss, netstat and docker ps.

연동 도구Docker
설치 방법 보기

이럴 때 유용합니다

  • Finding what holds an occupied port
  • Tracing a development server left running
  • Explaining an unknown or stuck process
  • Identifying the process holding a file lock

포함된 파일(1)

  • SKILL.md5.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

witr: why is this running?

witr traces a process, port, container or open file back to what started it and keeps it running (a systemd unit, launchd job, container, cron job, shell, PM2 or supervisor, a Windows service, ...), and flags anything suspicious. It only reads. It never stops, kills or changes anything.

Reach for it instead of chaining lsof, ps, ss, netstat and docker ps.

Before you start

Check that it's installed with witr --version. If it isn't, tell the user and suggest one of these; don't install anything without asking:

  • macOS or Linux: brew install witr, or curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash
  • Windows: winget install -e --id PranshuParmar.witr
  • With Go: go install github.com/pranshuparmar/witr/cmd/witr@latest

Always give a target and --json. Without a target, --json exits with code 4 and asks for one; a bare witr opens an interactive dashboard, or exits with code 4 when there's no terminal.

Pick the command

SituationCommand
Port already in use (EADDRINUSE)witr --port 3000 --json
A process by namewitr node --json (matches substrings; add --exact for the exact name)
A known PIDwitr --pid 1234 --json
A containerwitr --container web --json (name, image, Compose service or ID prefix)
What holds a file or lockwitr --file /var/lib/dpkg/lock --json
Just the chain of parentswitr --pid 1234 --short (one line) or --tree
Several things at oncewitr --port 3000 --port 5432 --json (a JSON list, one entry per target, in order)
A process's environmentwitr --pid 1234 --env --json
More detailadd --verbose (memory, I/O, open files, socket state)

Read the result

Check the exit code first:

ExitMeaningWhat to do
0Found, no warningsReport it
1Found, with warnings. Not a failureReport it and mention the warnings that matter
2Not foundNothing on this system runs or listens there; say so. For a port, Error may say something outside this system (another WSL distro, a VM) holds it
3Permission deniedIt belongs to another user; suggest re-running with sudo, and ask first
4Ambiguous or bad inputMatches lists the candidates: re-run with --pid for the right one, or fix the input
5Internal errorReport the Error
6Found, but what started it can't be traced (Linux, macOS, FreeBSD)The process that started it has exited; say so

With several targets, the most severe result wins.

Then the JSON (the full contract is in the README, section "7.4 JSON Output"):

  • Found: Process (PID, Command, Cmdline, User, StartedAt, WorkingDir, Sockets, ...), Ancestry (the chain from the top down to the process), Source (Type: systemd, launchd, bsdrc, container, shell, ssh, cron, supervisor, windows_service, init or unknown; Name; Description), Warnings, and Container when it runs in one.
  • Failed lookup: {Target, Error}, plus Matches when the target was ambiguous.
  • --short --json: a list of {PID, Command}. Where the process that started one has exited, that entry also has PPID and ParentExited: true.
  • A container whose processes aren't visible (Docker Desktop, a VM): {ContainerName, Image, Ports, ..., Note}.

Match on fields and exit codes, not on wording: the text of Error, Note, Description and warnings can change between releases.

Explain it to the user

Lead with the answer: what it is, and what started it. For example: "Port 3000 is held by node (pid 4821), started by PM2 from ~/work/api." Mention warnings that matter, such as a public bind, running as root, a deleted binary or a restart loop.

Freeing a port or stopping something

witr only explains. Don't kill or stop anything on your own: tell the user what holds the port and what manages it, and ask before acting.

When they agree, stop it through whatever manages it, or it will come straight back. Use Source.Type, Source.Name and Container:

Managed byStop with
systemdsystemctl stop <unit> (--user for a user unit)
launchdlaunchctl bootout gui/$(id -u)/<label> (sudo launchctl bootout system/<label> for a daemon)
FreeBSD rc (bsdrc)service <name> stop
Docker / Podmandocker stop <name> / podman stop <name>
PM2pm2 stop <name>
supervisorsupervisorctl stop <name>
Windows serviceStop-Service <name>
A shell or nothing traceablekill <pid> (Stop-Process -Id <pid> on Windows)

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

이 스킬의 문제 신고