business-ops
Business operations: strategy, technology, growth, competitive intelligence, support, finance, HR, legal, operations, sales, productivity, product management.
Safely start, supervise, and terminate shell processes: background jobs, PID capture, signals, traps, cleanup verification.
$ npx -y skills add notque/vexjoy-agent --skill shell-process-patterns --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/shell-process-patternsContext preview
The summary Claude sees to decide when to auto-load this skill.
Safely start, supervise, and terminate shell processes: background jobs, PID capture, signals, traps, cleanup verification.
name: shell-process-patterns
description: "Safely start, supervise, and terminate shell processes: background jobs, PID capture, signals, traps, cleanup verification."
user-invocable: false
allowed-tools:
- Read
- Write
- Bash
- Grep
- Glob
- Edit
routing:
triggers:
- "background process"
- "nohup"
- "kill process"
- "pid lookup"
- "shell cleanup"
- "trap handler"
- "signal handling"
- "set -e"
- "bash process"
pairs_with:
- condition-based-waiting
- service-health-check
- cron-automation
category: processStart, supervise, and terminate shell processes safely -- background jobs, subshells, signal handlers, and cleanup. The dominant failure mode in this domain is silent state: a process that looks killed but still holds a port, a trap that looked fine but never fired on the child, a `set -e` script that kept running because `|| true` swallowed the error. This skill picks the right pattern, implements it with the real PID (not the wrapper), and verifies the observable state afterward.
| Pattern | Use When | Key Safety Bound | |---------|----------|------------------| | Background start | Ad-hoc long-running child in a script or session | Redirect fd 0/1/2, capture real PID, disown if parent exits | | Daemonization | Process must survive terminal close, become session leader | `setsid` + fd redirect + write PID file atomically | | PID resolution | Need to kill / inspect the actual worker | Re-query with `ss`/`pgrep`/`lsof`; `$!` is advisory, not authoritative | | Signal discipline | Graceful shutdown of a supervisor + children | SIGTERM first with timeout, SIGKILL as last resort, propagate to process group | | Trap + cleanup | Script must leave no orphans, lock files, or temp dirs | `trap ... EXIT` + verification (file gone, port free, PID dead) | | Strict-mode scripts | Any non-trivial bash script | `set -euo pipefail` with understood `||` and `if !` escape hatches |
**In scope:**
**Out of scope:**
| Signal | Load These Files | Why | |---|---|---| | starting a background process, `&`, `nohup`, `disown`, `setsid`, daemonize | `starting-processes.md` | Launch-time patterns and fd/session rules | | capturing the child PID, `$!` lies, port still listening after kill | `pid-resolution.md` | How to get the real PID and reconcile with observed state | | trap ordering, SIGTERM/SIGKILL, subshell signal inheritance, `exec` | `signals-and-traps.md` | Signal and trap discipline | | verifying a process is actually gone, lock file still present, port still bound | `cleanup-verification.md` | Kill-and-check pattern | | implementation patterns, detection commands, fix snippets, `set -e` + `||` | `preferred-patterns.md` | Catalog of gotchas with `rg`/`grep` detection and paired fixes |
Before implementing any pattern, read the repository CLAUDE.md and search the codebase for existing process-management patterns so the new code matches what is already there. Consistency with existing scripts beats local optimization.
Walk this decision tree. Pick exactly one pattern per task -- do not pre-emptively wrap a background process in a daemon, and do not add a trap handler for a script that runs for 50ms.
1. Are you starting a new process?
YES -> Is the parent going to exit before the child?
YES -> Daemonization (Step 3, load references/starting-processes.md)
NO -> Background start (Step 2, load references/starting-processes.md)
NO -> Continue
2. Do you need to kill or inspect a process someone else started?
YES -> PID resolution (Step 4, load references/pid-resolution.md)
NO -> Continue
3. Are you writing a supervisor (script that manages children)?
YES -> Signal + trap discipline (Step 5, load references/signals-and-traps.md)
NO -> Continue
4. Are you finishing a destructive operation (kill, rm, release)?
YES -> Cleanup verification (Step 6, load references/cleanup-verification.md)
NO -> Stop. The task may not belong in this skill.A background process in the same session (terminal open, parent stays alive). Load `references/starting-processes.md` for full rationale.
Minimum discipline:
1. **Redirect all three fds.** `cmd > log 2>&1 < /dev/null &` -- because an un-redirected background process inherits the terminal, and stray stdin reads block forever. 2. **Capture the PID defensively.** `$!` is the last backgrounded job's shell-level PID. If you wrap in `nohup`, you get the nohup PID, not the child. Re-query before acting on it (Step 4). 3. **Decide if `disown` is needed.** `disown $!` removes the job from the shell's job table so the shell does not send SIGHUP when it exits. Needed for scripts that start long-running children and return.
Minimal correct pattern (in-session, parent stays alive):
cmd > /tmp/cmd.log 2>&1 < /dev/null & pid=$! kill -0 "$pid
Essays and writing behind this toolkit live at vexjoy.com. VexJoy Agent connects plain-English requests to specialist agents, skills, and workflows. /do selects the knowledge and tools needed for your task.
Repo: notque/vexjoy-agent
Business operations: strategy, technology, growth, competitive intelligence, support, finance, HR, legal, operations, sales, productivity, product management.
Design workflows — UX copy, design systems, design critique, accessibility review, design handoff, user research synthesis. Use when writing UI copy, reviewing…
Marketing: SEO audits, campaign planning, content strategy, email sequences, competitive analysis, brand review, performance reporting.