Brand logo
HomeCloud ComputingSecuritySoftware DevelopmentAI ApplicationsStartupsGeneral
  1. Home
  2. /
  3. softwaredevelopment
  4. /
  5. proc-port-pid-name-path-workflow

ItInsightsWorld SoftwareDevelopment: A proc Command Pattern for Ports, PIDs, Names, and File Paths

Software teams rarely lose hours only to large architecture decisions. They also lose time when a local API cannot start, a CI runner waits for a process, or an unknown listener blocks port 3000. proc gives a single command grammar for those daily process tasks on macOS, Linux, and Windows. A target can be a listener on port 3000, one PID 1234, a process name such as node, or a file path such as ./server.py. Before state changes, it asks; --dry-run gives a preview.

Why this belongs in a software development toolbox

The delivery workflow is easier to repeat when process work uses one consistent surface: inspect, trace, stop, free, freeze, watch, and wait. Instead of switching between tools, flags, and fragile pipes, teams can describe the target once, confirm the action, and move on. Version 1.14.5 is available through brew, npm, cargo, Scoop, Nix, and Docker, so adoption does not depend on a single runtime or package manager.

One target grammar for process work

  • :3000 is a port selector. It points proc at the listener on port 3000. When paired with kill, that listener is stopped with SIGKILL; the tool asks before changing state, and --dry-run supplies a preview.
  • 1234 is a PID selector. Only PID 1234 is affected, and no other process is touched.
  • node is a name selector. proc matches it against process names and full command lines, so nodemon and node server.js are also included. With kill, every match is listed and ended only after confirmation.
  • :3000,:8080,node is a comma-separated target group. All listed selectors are handled together after one confirmation. If one process matches more than one selector, it is still acted on only once.
  • node --in . narrows node targets to the current folder and its subfolders. This prevents the editor or another project from being affected. Most commands accept --in.
  • ./server.py is a file selector for proc for. The path can be relative, absolute, or start with ~. It finds processes running server.py from this folder.
  • ./logs/app.log is also a file selector for proc for. It finds processes that have app.log open, such as a server that continues writing to the file.

Read-only discovery steps for delivery incidents

Use on to inspect without changing state

on is the first habit for risky process work. When the target is :3000, it reports the process listening on port 3000, together with name, PID, folder, CPU, memory, and running time. When the target is 1234, it reports PID 1234 and every port it listens on. When the target is node, it reports each matching process and its ports. With :3000,:8080,node, it answers all three at once: what is on port 3000 and port 8080, and which ports node processes hold. With node --in ., it reports only node processes started in this folder and their ports.

Use why to trace the origin

why walks the parent chain. With :3000, why moves back from the listener on port 3000 and reveals the start point, such as a terminal tab, tmux session, or editor. With 1234, it lists the parent chain that produced PID 1234, plus each parent's running time. With node, it traces every matching node process to whatever started it. With :3000,:8080, it returns one parent chain for each held port.

Use for, by, and in when the target is a file, name, or folder

for is used when the target is a file. ./server.py finds processes running server.py from this folder. ./logs/app.log finds processes that have app.log open, for example a server that is still writing to it. by is used for name matching. node lists every process whose name or command line matches node. node --in . restricts that list to the current folder and below. in is used for folder matching. . lists everything started in the folder you are in. ~/code/shop lists everything started in ~/code/shop, wherever you run the command, even if that folder was later deleted.

Use list, info, ports, and tree for broader inventory

list with no target walks through every process, sorted by highest resource use first. Adding node filters to matching processes. --status zombie returns zombie processes: exited work not cleaned up by its parent. --status accepts running, sleeping, stopped, or zombie. info 1234 returns folder, path, user, parent, status, CPU, memory, and uptime for PID 1234. info :3000 returns full details for the listener on port 3000. info node returns full details for every matching process. ports lists every listening port and the process using it. --exposed narrows output to ports reachable by other machines, meaning ports listening on 0.0.0.0 or ::. --local keeps localhost ports. --in . narrows to ports held by processes started in this folder. tree prints every process as parents and children. node prints each node process and the processes it started. 1234 --ancestors reverses direction, going from PID 1234 upward to the first process the system started.

Use orphans and stuck to find hidden waste

orphans finds processes whose parent has exited, such as dev servers left behind after a terminal closes. System services are omitted. With no target, it checks all parentless processes. --in . limits output to this folder. --in . --kill displays this folder's orphans, asks, and ends them. stuck locates busy long-running work. With no target, it finds processes running over 5 minutes that are currently using more than half a CPU. --kill ends the found stuck processes after display and confirmation.

Changing process state with confirmation first

Use kill for immediate termination

kill is the direct end path. :3000 kills the listener on port 3000 with SIGKILL. 1234 kills only PID 1234. node kills all matching node processes after listing and confirmation. :3000,:8080,node kills every listed selector after one confirmation. node --in . kills only node processes located under the current folder.

Use stop for polite termination

stop asks the target to leave cleanly first. :3000 asks the listener on port 3000 to exit with SIGTERM, then forces it after 10 seconds if it remains. 1234 follows the same pattern for PID 1234. node gracefully stops every matching process after confirmation. node --in . stops only node processes under the current folder. :3000 --signal HUP sends HUP instead of SIGTERM, and many servers treat HUP as reload your config.

Use free when the real goal is an open port

free is for ports only. :3000 politely and forcefully stops the process holding port 3000, then confirms the port is truly free. :3000,:8080 frees both ports in one operation. Commas combine ports.

Use freeze, thaw, and unstick for pause and recovery

freeze pauses without ending. On macOS and Linux, node sends SIGSTOP to every matching process. 1234 pauses PID 1234, useful for a heavy build while you need the machine back. :3000 pauses the listener, leaving connections hanging until thaw. thaw resumes. node resumes previously frozen node processes with SIGCONT. 1234 resumes PID 1234, regardless of whether proc freeze or Ctrl+Z paused it. unstick attempts recovery. With no target, it finds stuck processes, wakes them with SIGCONT, and interrupts them like Ctrl+C; nothing is terminated unless --force is supplied. 1234 attempts the same gentle recovery for that PID. node --force falls back to terminating stuck node processes with SIGTERM, then SIGKILL.

Watching, waiting, and release pipeline use

Use watch for live monitoring

watch is the continuous view. With no target, it displays a busy-first table refreshed every 2 seconds; q quits. node monitors only node processes. :3000 monitors the listener on port 3000.

Use wait to block until a target exits

wait prevents scripts from moving on too early. :3000 waits until the process on port 3000 has exited, letting scripts launch the next server. 1234 waits for PID 1234. node --timeout 60 abandons the wait after 60 seconds if node processes remain, preventing CI from hanging. --timeout exits 1 when it gives up.

Shared behavior across commands

Every command shares the same target forms. Almost all commands support --in for project scoping, --json for machine-readable output, and --dry-run to preview changes. Listing flags, such as --status and --exposed, narrow search results. --kill applies the listed command's action to discovered processes and asks first, like proc kill. proc covers nineteen commands across three jobs.

Comparison with shell pipelines

The same jobs can be done with lsof, ps, grep, pgrep, xargs, kill, and sleep, but proc removes the need to remember lsof flags or pipe PIDs into kill.

TaskShell pipelineproc command
What is on port 3000?lsof -i :3000 -P -nproc on :3000
Why is it there?lsof -i :3000, then ps -o ppid= up the chainproc why :3000
Free the portlsof -t -i:3000 | xargs kill && sleep 1 && lsof -i:3000proc free :3000
Wait for it to exitwhile ps aux | grep node | grep -v grep; do sleep 5; doneproc wait node
Pause a processkill -STOP $(pgrep node)proc freeze node
Find leftoversNo standard toolproc orphans --in .

Installation and packaging

Install by running brew install yazeed/proc/proc; Version 1.14.5 also reaches users through npm, cargo, Scoop, Nix, and Docker.

Practical scenario

A common delivery interruption happens when a developer cannot start a local API because port 3000 is already taken. proc can locate the old tmux session that holds it, release port 3000, and clean up the other processes left running.

Automation and agent use

The tool is aimed at scripts and coding agents. Each command emits one JSON document with --json, and exit codes are fixed: 0 success, 1 error, 2 not found, 3 permission denied, 4 invalid input. --dry-run only identifies what would be touched. The agent skill teaches Claude Code, Codex, Cursor, Gemini CLI, and others when to use proc. In the example proc on :8080 --json | jq '.process | {pid, cwd, uptime_secs}', the sample values are pid 177, cwd /home/dev/code/shop, and uptime_secs 35.

Common pitfalls

  • A bare name such as node can match more than one intended process. Use --in . when the target should be limited to the current project folder.
  • freeze does not end the process. It pauses it, and network connections may hang until thaw or a later stop.
  • A CI job can hang if it waits for a long-lived name without a limit. Use --timeout 60 and handle the failed wait through exit code 1.
  • --exposed should be used when you care about ports reachable by other machines, meaning ports listening on 0.0.0.0 or ::.

Action recommendations

  1. Start with on or why before changing state, especially for :3000, 1234, or node.
  2. Scope name searches with --in . when several node processes may exist across folders.
  3. Use free when the goal is a truly open port, not just an attempt to stop a process.
  4. Add wait with a bounded timeout to scripts and CI paths so process cleanup remains predictable.

FAQ

What does a leading colon mean?

A leading colon means a port. The selector :3000 targets the listener on port 3000.

What does a bare number mean?

A bare number means a PID. The selector 1234 targets only PID 1234.

Why does node match nodemon?

proc compares the name against process names and full command lines, so node also finds nodemon and node server.js.

Can changes be previewed?

Yes. Use --dry-run to preview what would be touched before any process state is changed.

Related notes

  • What's new in proc: nineteen releases since March — October 25, 2026
  • Unix signals: the complete reference — March 10, 2026
  • nohup vs disown vs &: running background processes — March 10, 2026
  • Managing child processes in Node.js — March 10, 2026
Brand logo

IT Insights

Cloud & Infrastructure Practice Media for Enterprise Technology Decision-Makers

Cloud ComputingSecuritySoftware DevelopmentAI ApplicationsStartupsGeneralAI Data News Global

© 2026 IT Insights.

Cookie Notice

We use cookies to improve your experience and analyze website traffic. Read our Privacy Policy to learn more.