Reference skill for writing commands, scripts, and configuration across Unix shells. Detects
the target shell from context and routes to the appropriate reference.
pk() { # usage: pk <pattern>
local pattern=$1 pids
pids=(${(f)"$(pgrep -af -- "$pattern")"}) # -f matches full cmdline (spaces ok)
(( $#pids )) || { print -u2 "no match"; return 1 }
printf '%s\n' "${pids[@]}" # show PID + cmdline
read -q "?kill these? [y/N] " || { print; return 1 }
print
for line in $pids; do kill_gracefully ${line%% *} 3; done
}
Quoting rules
Syntax
Expansion
Use for
"double"
$var, $(cmd), ${param} expand; \ escapes
Most strings with variables
'single'
Nothing expands, completely literal
Regexes, JSON, strings with $ or !
$'ansi'
\n, \t, ' interpreted (bash/zsh)
Strings needing literal control chars
\char
Escapes one character
Single special chars in unquoted context
Golden rule: when in doubt, double-quote. "$var" is almost always correct. Unquoted $var
causes word splitting (in sh/bash) or glob expansion.
Exit codes
Code
Meaning
0
Success
1
General error
2
Misuse of shell builtin
126
Command found but not executable
127
Command not found
128+N
Killed by signal N (e.g., 130 = Ctrl+C / SIGINT)
Common portable idioms
# Check if command exists
command -v git >/dev/null 2>&1 || { echo "git required" >&2; exit 1; }
# Default variable value
: "${VAR:=default}" # set VAR to "default" if unset or empty
name="${1:-anonymous}" # parameter default
# Temporary file (portable)
tmpfile=$(mktemp) || exit 1
trap 'rm -f "$tmpfile"' EXIT
# Read file line by line
while IFS= read -r line; do
printf '%s\n' "$line"
done < file.txt
# Loop over glob results
for f in *.txt; do
[ -e "$f" ] || continue # guard against no matches (POSIX sh)
echo "$f"
done
Completions Quick Reference (Zsh)
Zsh's completion system (compsys) handles subcommand routing natively. Minimal working
example for a CLI tool with subcommands:
#compdef mycli
_mycli() {
local -a subcmds=(
'init:Initialize a new project'
'build:Build the project'
'deploy:Deploy to target environment'
)
_arguments -C \
'(-h --help)'{-h,--help}'[Show help]' \
'1:command:->subcmd' \
'*::arg:->args'
case $state in
subcmd) _describe 'command' subcmds ;;
args)
case $words[1] in
deploy) _arguments '--env[Target environment]:env:(dev staging prod)' ;;
esac
;;
esac
}
Place in a file named _mycli on your fpath, then ensure the directory is registered:
# In .zshrc, BEFORE compinit:
fpath=(~/.zsh/completions $fpath)
autoload -Uz compinit && compinit
Or source inline with compdef _mycli mycli (no fpath needed). The reference files have
deeper coverage: glob-qualified completions, _files, _hosts, _values, and async
completion patterns.
Verification Checklist
Before returning any shell script, check:
Shebang matches the target shell.#!/usr/bin/env bash for bash, #!/usr/bin/env zsh for zsh, #!/bin/sh for POSIX sh. Never #!/bin/bash (not portable across distros).
set -euo pipefail present for bash and zsh scripts. For POSIX sh: set -eu (no pipefail).
Variables are quoted."$var" not $var, unless word splitting is intentional.
No shell-isms in the wrong shell. No [[ ]] in #!/bin/sh. No BASH_SOURCE in zsh. No bash arrays in POSIX sh.
Glob safety. POSIX sh: guard with [ -e "$f" ] || continue. Zsh: use (N) qualifier. Bash: shopt -s nullglob or guard.
Array indexing matches the shell. Bash: 0-indexed. Zsh: 1-indexed. POSIX sh: no arrays.
printf over echo for anything non-trivial (echo behavior varies across shells and platforms).
references/ssh-tmux-autostart.md - safe shell startup pattern for interactive SSH sessions that attach to tmux without breaking non-interactive commands
Output Contract
See skills/_shared/output-contract.md for the full contract.
Skill name: COMMAND-PROMPT
Deliverable bucket:audits
Mode: conditional. When invoked to analyze, review, audit, or improve existing repo content, emit the full contract - boxed inline header, body summary inline plus per-finding detail in the deliverable file, boxed conclusion, conclusion table - and write the deliverable to docs/local/audits/command-prompt/<YYYY-MM-DD>-<slug>.md. When invoked to write a script, dotfile, or completion / answer a question / teach a concept, respond freely: deliver the artifact or explanation inline without the contract, deliverable file, or conclusion table.
Severity scale:P0 | P1 | P2 | P3 | info (see shared contract; only used in audit/review mode).
Related Skills
firewall-appliance - OPNsense/pfSense uses tcsh/csh on FreeBSD. That skill handles the BSD firewall context; this skill covers tcsh syntax in general.
ansible - Ansible shell/command modules have their own idiosyncrasies beyond raw shell scripting. Use ansible for playbook work.
ci-cd - CI shell blocks run in restricted environments (no interactive features, possibly no bash). Use ci-cd for pipeline design; use this skill for the shell syntax within them.
networking - Linux network configuration (interfaces, routes, firewalls, DNS). Use networking for service and protocol administration; use this skill for the shell scripts that wrap or automate those tasks.
debian-ubuntu - Debian/Ubuntu system administration (packages, services, cloud-init). Use debian-ubuntu for distro-level operations; use this skill for the shell scripting patterns within those tasks.
rhel-fedora - RHEL/Fedora system administration (dnf, systemd, SELinux, subscription-manager). Use rhel-fedora for distro-level operations; use this skill for the shell scripting patterns within those tasks.
Rules
Detect the shell first. Check shebang, file extension, or ask. Don't assume bash when the user might mean zsh.
Load the right reference. Don't wing zsh arrays or bash parameter expansion from memory - the subtle differences justify loading the reference every time.
Shebang is #!/usr/bin/env <shell>. Not #!/bin/bash. The env form is portable across distros. Exception: #!/bin/sh for POSIX scripts (this IS the standard form).
set -euo pipefail in every bash/zsh script. No exceptions for scripts beyond a one-liner.
User's interactive shell is zsh. When writing commands for the user to run locally, use zsh syntax. Bash for scripts and remote machines unless the script specifically needs zsh.
Don't mix shell syntaxes. A bash script uses bash idioms. A zsh script uses zsh idioms. "Works in both" compromises use neither well and confuse readers.
Quote your variables."$var" is the default. Unquoted $var is the exception that needs justification.
1---2name: command-prompt3description: · Write/debug shell commands, scripts, dotfiles, completions for zsh, bash, POSIX sh, fish. Triggers: 'shell', 'script', '.zshrc', '.bashrc', 'alias', 'completion', 'trap'. Not for CI blocks (use ci-cd).4license: MIT5---67# Command Prompt: Shell Scripting and Configuration
89Reference skill for writing commands, scripts, and configuration across Unix shells. Detects
10the target shell from context and routes to the appropriate reference.
1112**Target versions** (May 2026):
13- Zsh: 5.10
14- Bash: 5.3
15- Fish: 4.6
16- Nushell: 0.111
17- Tcsh: 6.24
18- Dash: 0.5.13
1920## When to use
2122- Writing shell commands, scripts, or one-liners
23- Configuring dotfiles (`.zshrc`, `.bashrc`, `.profile`, `config.fish`)
24- Writing completions, shell functions, or aliases
25- Porting scripts between shells
26- Debugging shell-specific behavior (globbing, arrays, expansion, quoting)
27- Setting up oh-my-zsh, starship, p10k, or other shell frameworks
28- Choosing which shell to target for a new script
29- Writing interactive commands on the user's local machine (zsh)
3031## When NOT to use
3233- Remote FreeBSD/OPNsense/pfSense commands - use **firewall-appliance** (handles tcsh/csh in the BSD context)
34- Ansible shell/command modules - use **ansible** (module gotchas differ from raw shell)
35- CI/CD pipeline shell blocks - use **ci-cd** (restricted environments, no interactive features)
36- General Linux sysadmin that isn't shell-specific - just do the task directly
3738---
3940## AI Self-Check
4142Before returning any generated shell script or command, verify:
4344- [ ] Shebang matches the detected target shell (not assumed bash)
45- [ ] `set -euo pipefail` (bash/zsh) or `set -eu` (POSIX sh) present in scripts
46- [ ] All variables double-quoted (`"$var"`) unless word splitting is intentional
47- [ ] No shell-isms from the wrong shell (no `[[ ]]` in `#!/bin/sh`, no `BASH_SOURCE` in zsh)
48- [ ] Array indexing correct for the target shell (bash: 0-indexed, zsh: 1-indexed)
49- [ ] `printf` used over `echo` for non-trivial output
50- [ ] Glob safety guards in place (empty-glob case handled)
51- [ ] No hardcoded paths for tools (`/usr/bin/git`) - use `command -v` or bare command names
52- [ ] Temp files use `mktemp` with cleanup traps, not hardcoded `/tmp/foo`
53- [ ] No secrets in command history (use `read -s` or environment variables)
54- [ ] **Current source checked**: dated versions, CLI flags, API names, and support windows are verified against primary docs before repeating them
55- [ ] **Hidden state identified**: local config, credentials, caches, contexts, branches, cluster targets, or previous runs are made explicit before acting
56- [ ] **Verification is real**: final checks exercise the actual runtime, parser, service, or integration point instead of only linting prose or happy paths
57- [ ] **Routing overlap checked**: overlapping skills, trigger terms, and "When NOT to use" boundaries are checked before returning guidance
58- [ ] **Spec claims verified**: claims about tool behavior, output contracts, or repo conventions are checked against current docs, scripts, or skill files
59- [ ] **Shell identified**: examples match POSIX sh, Bash, Zsh, or Fish semantics intentionally
60- [ ] **Quoting tested**: paths with spaces, empty variables, and glob characters behave safely
6162---
6364## Performance
6566- Use builtins and stream processing for large inputs; avoid command substitution that buffers entire files.
67- Prefer `rg`, `fd`, and targeted file lists when available, with portable fallbacks noted.
68- Avoid spawning subshells inside tight loops when `xargs`, arrays, or shell builtins fit.
697071---
7273## Best Practices
7475- Default to `set -euo pipefail` only when the script is written to handle those semantics.
76- Use `--` before user-controlled paths for commands that support it.
77- Preview destructive expansions before `rm`, `mv`, `chmod`, `chown`, or recursive edits.
787980## Workflow
8182### Step 1: Detect the target shell
8384Before writing any shell code, determine the target shell. Check these signals in order:
8586| Signal | How to check | Routes to |
87|--------|-------------|-----------|
88| **Shebang** | First line of existing script | `#!/usr/bin/env zsh` -> zsh, `#!/usr/bin/env bash` -> bash, `#!/bin/sh` -> posix-sh |
89| **File name/extension** | `.zsh`, `.zshrc`, `.zprofile`, `.zshenv` -> zsh; `.bash`, `.bashrc`, `.bash_profile` -> bash; `.fish`, `config.fish` -> fish | |
90| **User's shell** | Conversation context, `$SHELL` | User's local machine = zsh |
91| **Task type** | What the script does | See routing below |
9293### Task-based routing
9495| Task | Target shell | Why |
96|------|-------------|-----|
97| Interactive commands on user's machine | **zsh** | User's default shell |
98| Portable scripts (new) | **bash** | Widest deployment, good feature set |
99| Docker/CI containers | **bash** or **sh** | Containers often lack zsh |
100| Minimal Alpine/BusyBox scripts | **POSIX sh** | Only `ash`/`dash` available |
101| BSD system administration | **tcsh** | FreeBSD default (but see firewall-appliance skill) |
102| Cross-shell startup (env vars, PATH) | **POSIX sh** | `.profile` sourced by all POSIX shells |
103| Maximum portability requirement | **POSIX sh** | Only standard guaranteed on all Unixes |
104105### Step 2: Load the right reference
106107| Target shell | Reference file |
108|-------------|---------------|
109| Zsh | `references/zsh.md` (~680 lines, 14 sections) |
110| Bash | `references/bash.md` (~710 lines, 13 sections) |
111| POSIX sh | `references/posix-sh.md` (~490 lines, 10 sections) |
112| Fish, tcsh, nushell, others | `references/alt-shells.md` (~420 lines, 4 shells) |
113114**Don't load all references.** Pick the one that matches. If porting between two shells, load both.
115116### Step 3: Write code, then verify
117118Use the cross-shell comparison below for quick lookups. After writing, run through the
119Verification Checklist at the bottom of this section.
120121---
122123## Quick Cross-Shell Comparison
124125| Feature | POSIX sh | Bash | Zsh | Fish |
126|---------|----------|------|-----|------|
127| Arrays | no (use `$@`) | 0-indexed | **1-indexed** | lists (1-indexed) |
128| Assoc arrays | no | `declare -A` (4.0+) | `typeset -A` | no |
129| Glob `**/` | no | `shopt -s globstar` | built-in | built-in |
130| Failed glob | passes literal | passes literal | **error** | no match |
131| `[[ ]]` | no | yes | yes | no (use `test`) |
132| Process sub `<()` | no | yes | yes + `=()` | `(command \| psub)` |
133| Word splitting | on unquoted `$var` | on unquoted `$var` | **no** | **no** |
134| Arithmetic | `$(( ))` only | `$(( ))`, `(( ))`, `let` | `$(( ))`, `(( ))` | `math` |
135| String lowercase | - | `${var,,}` | `${var:l}` | `string lower` |
136| Completions | none | basic (bash-completion) | powerful (compsys) | powerful (built-in) |
137| Config file | `.profile` | `.bashrc` | `.zshrc` | `config.fish` |
138| Shebang | `#!/bin/sh` | `#!/usr/bin/env bash` | `#!/usr/bin/env zsh` | `#!/usr/bin/env fish` |
139| Script safety | `set -eu` | `set -euo pipefail` | `set -euo pipefail` | N/A (strict by default) |
140| Non-forking cmd sub | no | `${ cmd; }` (5.3+) | `${ cmd }` (5.10+) | no |
141142---
143144## Universal Patterns (All POSIX Shells)
145146These work in sh, bash, and zsh. Fish has different syntax for most of these - see the
147alt-shells reference.
148149### Piping and redirection
150151| Pattern | Effect |
152|---------|--------|
153| `cmd1 \| cmd2` | Pipe stdout of cmd1 to stdin of cmd2 |
154| `cmd > file` | Redirect stdout to file (overwrite) |
155| `cmd >> file` | Redirect stdout to file (append) |
156| `cmd 2> file` | Redirect stderr to file |
157| `cmd &> file` | Redirect both stdout and stderr (bash/zsh, not POSIX) |
158| `cmd 2>&1` | Redirect stderr to stdout |
159| `cmd > /dev/null 2>&1` | Silence all output (POSIX-portable) |
160| `cmd < file` | Feed file as stdin |
161| `cmd <<'EOF'` | Here document (single-quoted delimiter = no expansion) |
162| `cmd <<< "string"` | Here string (bash/zsh, not POSIX) |
163| `cmd1 \| tee file \| cmd2` | Send stdout to both file and cmd2 |
164165### Chaining
166167| Pattern | Behavior |
168|---------|----------|
169| `cmd1 ; cmd2` | Run sequentially, ignore exit codes |
170| `cmd1 && cmd2` | Run cmd2 only if cmd1 succeeds (exit 0) |
171| `cmd1 \|\| cmd2` | Run cmd2 only if cmd1 fails (exit non-0) |
172| `cmd &` | Run in background |
173| `cmd1 && cmd2 \|\| cmd3` | Poor man's if/else (**not reliable** - cmd3 runs if cmd2 fails too) |
174175### Job control
176177| Command | Effect |
178|---------|--------|
179| `Ctrl+Z` | Suspend foreground job |
180| `bg` / `bg %N` | Resume job in background |
181| `fg` / `fg %N` | Resume job in foreground |
182| `jobs` | List background jobs |
183| `kill %N` | Kill job by number |
184| `wait` | Wait for all background jobs |
185| `wait $PID` | Wait for specific PID |
186| `disown %N` | Detach job from shell (survives logout) |
187188### Signals and traps
189190```sh
191# Cleanup on exit (works in sh, bash, zsh)
192cleanup() {
193 rm -f "$tmpfile"
194}
195trap cleanup EXIT INT TERM
196197# Ignore a signal
198trap '' HUP
199200# Common signals: EXIT (0), HUP (1), INT (2), TERM (15), USR1 (10), USR2 (12)
201202# Graceful kill with SIGTERM -> wait -> SIGKILL escalation
203kill_gracefully() {
204 local pid=$1 timeout=${2:-5}
205 kill -TERM "$pid" 2>/dev/null || return
206 local i=0
207 while kill -0 "$pid" 2>/dev/null && [ $i -lt $timeout ]; do
208 sleep 1; i=$((i+1))
209 done
210 kill -0 "$pid" 2>/dev/null && kill -KILL "$pid"
211}
212```
213214**Interactive "kill by name" (zsh)** - covers search, space-safe names, confirm, TERM->KILL escalation:
215216```zsh
217pk() { # usage: pk <pattern>
218 local pattern=$1 pids
219 pids=(${(f)"$(pgrep -af -- "$pattern")"}) # -f matches full cmdline (spaces ok)
220 (( $#pids )) || { print -u2 "no match"; return 1 }
221 printf '%s\n' "${pids[@]}" # show PID + cmdline
222 read -q "?kill these? [y/N] " || { print; return 1 }
223 print
224 for line in $pids; do kill_gracefully ${line%% *} 3; done
225}
226```
227228### Quoting rules
229230| Syntax | Expansion | Use for |
231|--------|-----------|---------|
232| `"double"` | `$var`, `$(cmd)`, `${param}` expand; `\` escapes | Most strings with variables |
233| `'single'` | Nothing expands, completely literal | Regexes, JSON, strings with `$` or `!` |
234| `$'ansi'` | `\n`, `\t`, `'` interpreted (bash/zsh) | Strings needing literal control chars |
235| `\char` | Escapes one character | Single special chars in unquoted context |
236237**Golden rule**: when in doubt, double-quote. `"$var"` is almost always correct. Unquoted `$var`
238causes word splitting (in sh/bash) or glob expansion.
239240### Exit codes
241242| Code | Meaning |
243|------|---------|
244| 0 | Success |
245| 1 | General error |
246| 2 | Misuse of shell builtin |
247| 126 | Command found but not executable |
248| 127 | Command not found |
249| 128+N | Killed by signal N (e.g., 130 = Ctrl+C / SIGINT) |
250251### Common portable idioms
252253```sh
254# Check if command exists
255command -v git >/dev/null 2>&1 || { echo "git required" >&2; exit 1; }
256257# Default variable value
258: "${VAR:=default}" # set VAR to "default" if unset or empty
259name="${1:-anonymous}" # parameter default
260261# Temporary file (portable)
262tmpfile=$(mktemp) || exit 1
263trap 'rm -f "$tmpfile"' EXIT
264265# Read file line by line
266while IFS= read -r line; do
267 printf '%s\n' "$line"
268done < file.txt
269270# Loop over glob results
271for f in *.txt; do
272 [ -e "$f" ] || continue # guard against no matches (POSIX sh)
273 echo "$f"
274done
275```
276277---
278279## Completions Quick Reference (Zsh)
280281Zsh's completion system (`compsys`) handles subcommand routing natively. Minimal working
282example for a CLI tool with subcommands:
283284```zsh
285#compdef mycli
286287_mycli() {
288 local -a subcmds=(
289 'init:Initialize a new project'
290 'build:Build the project'
291 'deploy:Deploy to target environment'
292 )
293294 _arguments -C \
295 '(-h --help)'{-h,--help}'[Show help]' \
296 '1:command:->subcmd' \
297 '*::arg:->args'
298299 case $state in
300 subcmd) _describe 'command' subcmds ;;
301 args)
302 case $words[1] in
303 deploy) _arguments '--env[Target environment]:env:(dev staging prod)' ;;
304 esac
305 ;;
306 esac
307}
308```
309310Place in a file named `_mycli` on your `fpath`, then ensure the directory is registered:
311312```zsh
313# In .zshrc, BEFORE compinit:
314fpath=(~/.zsh/completions $fpath)
315autoload -Uz compinit && compinit
316```
317318Or source inline with `compdef _mycli mycli` (no fpath needed). The reference files have
319deeper coverage: glob-qualified completions, `_files`, `_hosts`, `_values`, and async
320completion patterns.
321322---
323324## Verification Checklist
325326Before returning any shell script, check:
327328- [ ] **Shebang matches the target shell.** `#!/usr/bin/env bash` for bash, `#!/usr/bin/env zsh` for zsh, `#!/bin/sh` for POSIX sh. Never `#!/bin/bash` (not portable across distros).
329- [ ] **`set -euo pipefail`** present for bash and zsh scripts. For POSIX sh: `set -eu` (no `pipefail`).
330- [ ] **Variables are quoted.** `"$var"` not `$var`, unless word splitting is intentional.
331- [ ] **No shell-isms in the wrong shell.** No `[[ ]]` in `#!/bin/sh`. No `BASH_SOURCE` in zsh. No bash arrays in POSIX sh.
332- [ ] **Glob safety.** POSIX sh: guard with `[ -e "$f" ] || continue`. Zsh: use `(N)` qualifier. Bash: `shopt -s nullglob` or guard.
333- [ ] **Array indexing matches the shell.** Bash: 0-indexed. Zsh: 1-indexed. POSIX sh: no arrays.
334- [ ] **`printf` over `echo`** for anything non-trivial (echo behavior varies across shells and platforms).
335336---
337338## Reference Files
339340- `references/zsh.md` - Zsh 5.9/5.10 patterns, glob qualifiers, arrays, parameter expansion, completions, autoloading, dotfile config, prompt hooks, zsh-only features, 5.10 additions (non-forking `${ }`, namerefs, SRANDOM), bash porting matrix
341- `references/bash.md` - Bash 5.3 patterns, parameter expansion, arrays, conditionals, process substitution, error handling, traps, heredocs, coprocesses, bash 5.x features (non-forking `${ cmd; }`, GLOBSORT, SRANDOM), script template
342- `references/posix-sh.md` - Portable POSIX sh patterns, what's POSIX and what's not, bashism avoidance checklist, which-sh-am-I, arithmetic, parameter expansion, portable conditionals
343- `references/alt-shells.md` - Fish 4.6 (syntax, functions, completions, config, 4.6 additions), tcsh/csh 6.24 (syntax, when you'll encounter it), nushell 0.111 (structured pipelines, types), elvish 0.22/oils 0.37 (brief)
344- `references/ssh-tmux-autostart.md` - safe shell startup pattern for interactive SSH sessions that attach to tmux without breaking non-interactive commands
345346## Output Contract
347348See `skills/_shared/output-contract.md` for the full contract.
349350- **Skill name:** COMMAND-PROMPT
351- **Deliverable bucket:** `audits`
352- **Mode:** conditional. When invoked to **analyze, review, audit, or improve** existing repo content, emit the full contract - boxed inline header, body summary inline plus per-finding detail in the deliverable file, boxed conclusion, conclusion table - and write the deliverable to `docs/local/audits/command-prompt/<YYYY-MM-DD>-<slug>.md`. When invoked to **write a script, dotfile, or completion / answer a question / teach a concept**, respond freely: deliver the artifact or explanation inline without the contract, deliverable file, or conclusion table.
353- **Severity scale:** `P0 | P1 | P2 | P3 | info` (see shared contract; only used in audit/review mode).
354355## Related Skills
356357- **firewall-appliance** - OPNsense/pfSense uses tcsh/csh on FreeBSD. That skill handles the BSD firewall context; this skill covers tcsh syntax in general.
358- **ansible** - Ansible `shell`/`command` modules have their own idiosyncrasies beyond raw shell scripting. Use ansible for playbook work.
359- **ci-cd** - CI shell blocks run in restricted environments (no interactive features, possibly no bash). Use ci-cd for pipeline design; use this skill for the shell syntax within them.
360- **networking** - Linux network configuration (interfaces, routes, firewalls, DNS). Use networking for service and protocol administration; use this skill for the shell scripts that wrap or automate those tasks.
361- **debian-ubuntu** - Debian/Ubuntu system administration (packages, services, cloud-init). Use debian-ubuntu for distro-level operations; use this skill for the shell scripting patterns within those tasks.
362- **rhel-fedora** - RHEL/Fedora system administration (dnf, systemd, SELinux, subscription-manager). Use rhel-fedora for distro-level operations; use this skill for the shell scripting patterns within those tasks.
363364## Rules
3653661. **Detect the shell first.** Check shebang, file extension, or ask. Don't assume bash when the user might mean zsh.
3672. **Load the right reference.** Don't wing zsh arrays or bash parameter expansion from memory - the subtle differences justify loading the reference every time.
3683. **Shebang is `#!/usr/bin/env <shell>`.** Not `#!/bin/bash`. The env form is portable across distros. Exception: `#!/bin/sh` for POSIX scripts (this IS the standard form).
3694. **`set -euo pipefail` in every bash/zsh script.** No exceptions for scripts beyond a one-liner.
3705. **User's interactive shell is zsh.** When writing commands for the user to run locally, use zsh syntax. Bash for scripts and remote machines unless the script specifically needs zsh.
3716. **Don't mix shell syntaxes.** A bash script uses bash idioms. A zsh script uses zsh idioms. "Works in both" compromises use neither well and confuse readers.
3727. **Quote your variables.** `"$var"` is the default. Unquoted `$var` is the exception that needs justification.
Run npx skillmds add majiayu000/command-prompt in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
· Write/debug shell commands, scripts, dotfiles, completions for zsh, bash, POSIX sh, fish. Triggers: 'shell', 'script', '.zshrc', '.bashrc', 'alias', 'completion', 'trap'. Not for CI blocks (use ci-cd). It is listed under AI & ML on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: docs only. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
majiayu000 (@majiayu000) published this skill. Their other Agent Skills are listed on their SkillMD profile.