linux-bash-scripting
/linux-bash-scripting
Pomaga pisać i recenzować przenośne skrypty Bash sk-* dla tego silnika: prymitywy common.sh, flagi, tryby próbne i bramki bezpieczeństwa.
- Autor
- peterbamuhigire ↗
- Repozytorium
- linux-skills ↗
- Licencja
- MIT
- Ostatnia zmiana repozytorium
- 24.10.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 5
- Skrypty
- 1
- Komentarze HTML
- 2
- Adresy URL w SKILL.md
- 0
Brak sygnałów. Repozytorium zmienione 24.10.2026, bez odwołań do wycofanych modeli i API.
MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.
- 1 skrypt w paczce. Przejrzyj je przed instalacją, bo Claude może je uruchomić.
- SKILL.md zawiera komentarze HTML (2). Nie widać ich w podglądzie Markdown, a model je czyta.
Skrypty: references/script-template.sh
Co robi i kiedy
Pomaga pisać i recenzować przenośne skrypty Bash sk-* dla tego silnika: prymitywy common.sh, flagi, tryby próbne i bramki bezpieczeństwa.
Oryginalny opis (EN)
Use when writing or reviewing portable sk-* Bash scripts for this engine, including common.sh primitives, flags, dry runs, and safety gates; use linux-repo-sync for Git-update behaviour and not for one-off commands.
Jak działa
- Distro support
- Use when
- Do not use when
- Required Inputs
- Capability Contract
- Degraded Mode
- Decision Rules
- Workflow
- Evidence Produced
- Quality standards
Podgląd SKILL.md
---
name: linux-bash-scripting
description: "Use when writing or reviewing portable sk-* Bash scripts for this engine, including common.sh primitives, flags, dry runs, and safety gates; use linux-repo-sync for Git-update behaviour and not for one-off commands."
license: MIT
metadata:
portable: true
compatible_with: [claude-code, codex]
author: Peter Bamuhigire
author_url: techguypeter.com
author_contact: "+256784464178"
---
# Linux Bash Scripting — the meta-skill
## Distro support
This meta-skill is **how** sk-* scripts stay two-family. A script must never
hardcode `apt`, `ufw`, or `apache2` — it calls the `common.sh` primitives, which
resolve to the right tool for the detected family (Debian/Ubuntu or the RHEL
family: Fedora, RHEL, CentOS Stream, Rocky, Alma, Oracle).
| Need | Don't hardcode | Use this primitive |
|---|---|---|
| Detect the family | parse `/etc/os-release` | `detect_distro` → `SK_DISTRO_FAMILY`, `SK_PKG` |
| Install packages | `apt install` / `dnf install` | `pkg_install <pkg>...` |
| Query installed | `dpkg -s` / `rpm -q` | `pkg_is_installed <pkg>` |
| Enable extra repo | `add-apt-repository` / EPEL | `ensure_epel` (no-op off-RHEL & on Fedora) |
| Service unit name | `apache2` / `httpd` | `svc_name apache` |
| Open a firewall port | `ufw allow` / `firewall-cmd` | `firewall_allow <port|service>` |
| Web config dir / reload | `sites-available` / `conf.d` | `web_conf_dir`, `web_reload` |
| Gate the script | check `$ID` | `require_family <debian|rhel|any>` |
Full contract: [`references/common-sh-contract.md`](references/common-sh-contract.md).
Plan: [`docs/multi-distro/plan.md`](../../docs/multi-distro/plan.md).
<!-- dual-compat-start -->
## Use when
- Writing a new `sk-*` script in this repository.
- Reviewing or refactoring an existing script under `scripts/`.
- Checking whether a script matches the engine contract, flag model, and safety rules.
## Do not use when
- The task is a one-off shell command or an operational fix that will not become a repo script.
- The implementation language is not Bash.
## Required Inputs
| Artefact | Source | Required? | If absent |
|---|---|---|---|
| Target skill, script name, and inventory entry | Request and script inventory | yes | Stop before scaffolding an unowned script |
| Behaviour, inputs, decision flags, and side effects | Operator and owning specialist skill | yes | Produce a review/questions list; do not invent defaults |
| Distro support and service/package mappings | Owning skill and `common.sh` contract | yes | Require `any` only when both families are verified |
| Test fixtures and mutation authority | Maintainer and safe test host | for execution | Limit work to static review and dry-run design |
## Capability Contract
Review uses read/search access and is read-only by default. Editing an owned script requires explicit implementation authority; executing privileged or destructive paths requires separate test-host approval. Never use production state to discover what an unsafe script does.
## Degraded Mode
Without shellcheck, a Bash runtime, root, or both distro families, complete static checks and label runtime, privilege, or family behaviour unassessed. Do not claim portability or safety from source inspection alone.
## Decision Rules
| Choice | Action | Failure avoided |
|---|---|---|
| Input requires a prompt | Add a named decision flag and `require_flag` under `--yes` | Invented unattended defaults |
| Operation changes important config | Backup, atomic write, native validation, then reload | Partial config and outage |
| Package/service differs by family | Use `common.sh` primitive | Debian-only automation |
| Operation is destructive | Typed confirmation plus explicit non-interactive flag | Accidental deletion |
## Workflow
For every mutating `sk-*` script, apply the safe reversible operations standard: detect the family, capture a before state, support a dry-run or no-op path, make the operation idempotent, use atomic writes where files change, preserve ownership/labels, and expose a bounded rollback or recovery path. A script is not release-ready until its success path, already-correct path, invalid-input path, and rollback/recovery evidence are tested for both distro families or explicitly marked unassessed.
1. Read the owning skill, engine spec, inventory, template, and `common.sh` contract.
2. Define inputs, effects, decisions, exit codes, rollback, and family support; stop on an unresolved destructive default.
3. Scaffold or review the six-section structure and standard flags.
4. Implement through shared primitives with quoted inputs, safe temp files, backups, and native validators.
5. Test help, bad inputs, `--yes`, dry run, interruption, idempotency, and both families where claimed.
6. Recover failed mutation from backup, then run shellcheck/engine lint and reconcile manifest documentation.
## Evidence Produced
| Artefact | Acceptance |
|---|---|
| Script validation evidence | Includes shellcheck/engine lint, help, dry run, negative paths, distro matrix, diff, and manifest alignment |
## Quality standards
- Every script must be safe, idempotent by default, and compatible with human and agent callers.
- `common.sh` is mandatory; do not reinvent shared behavior.
- Help output, failure modes, and validation-before-reload rules must be explicit.
## Anti-patterns
- Bypassing `common.sh`. Fix: use its output, guard, package, service, and file primitives.
- Treating `--yes` as permission to invent defaults. Fix: require every decision flag.
- Shipping without a manifest entry. Fix: reconcile the owning skill and inventory.
- Using `set -e`. Fix: handle expected failures and preserve `set -uo pipefail`.
- Writing important files with direct redirection. Fix: back up and use atomic writes.
- Claiming family portability after one-family testing. Fix: test both or mark one unassessed.
- Handing the user a script by a long, scratch, or skill-directory path. Fix: install it as `sk-*` or copy it to `~/<name>.sh` (see "Handing a script to a user").
## Outputs
| Artefact | Consumer | Acceptance condition |
|---|---|---|
| Conforming script or review | Maintainer | Contract, flags, safety, and family rules are satisfied |
| Test evidence | Reviewer | Covers help, errors, dry run, destructive gates, and lint |
| Manifest update | Installer | Script source, name, core status, and purpose agree |
## Worked Example
For `sk-cifs-mount`, make share, mount point, and credentials source explicit flags. Under `--yes`, missing any required choice exits 2; dry run prints package, credential-file, mount, and fstab actions without exposing the password or writing files.
<!-- dual-compat-end -->
## References
- [`../../docs/continuous-improvement/safe-reversible-operations-standard.md`](../../docs/continuous-improvement/safe-reversible-operations-standard.md)
- [`../../docs/continuous-improvement/two-family-validation-and-recovery.md`](../../docs/continuous-improvement/two-family-validation-and-recovery.md)
- [`references/script-template.sh`](references/script-template.sh)
- [`references/common-sh-contract.md`](references/common-sh-contract.md)
- [`references/interactive-ux.md`](references/interactive-ux.md)
- [`docs/engine-design/spec.md`](../../docs/engine-design/spec.md)
This skill is the foundation every other script in `linux-skills` is built on.
Before writing a new `sk-*` script, or reviewing an existing one, load this
skill.
It defines:
1. The canonical script template (six-section layout from *Pro Bash*).
2. The `common.sh` library contract (what functions exist, what they do).
3. The standard flag set every script must support.
4. Interactive UX rules (prompts, confirmations, output).
5. Safety patterns every script must follow.
6. How Claude Code invokes these scripts non-interactively.
Read the full engine spec in [`docs/engine-design/spec.md`](../../docs/engine-design/spec.md)
and the script catalogue in [`docs/engine-design/script-inventory.md`](../../docs/engine-design/script-inventory.md)
for context.
---
## When to use this skill
- Before writing any new script in `scripts/`.
- Before reviewing a script that another person (or another Claude session) wrote.
- When asked "how do I make a script interactive / secure / safe / dry-runnable / help-printing?"
- When unsure which library function to call from `common.sh`.
## When NOT to use this skill
- For one-liners and ad-hoc commands (don't over-engineer a `grep`).
- For Python, Node.js, Go, or any non-Bash tooling.
- For scripts that will never live in this repo (e.g. throwaway fixes).
---
## The canonical script template
Every `sk-*` script must start from this six-section layout. See
[`references/script-template.sh`](references/script-template.sh) for a
copy-pasteable version. The `sk-new-script` wrapper is not shipped in this
checkout; copy and adapt the reference template manually into the owning
skill's `scripts/` directory.
The six sections in order:
1. **Metadata header** — `#:` prefixed comments with Title, Synopsis,
Description, Author, Contact, Version. Grep-extractable. Author line must
always read `#: Author: Peter Bamuhigire <techguypeter.com>`.
2. **Library + safety** — `set -uo pipefail` then `source` of `common.sh`.
Never use `set -e` (it interacts badly with traps and function return
codes).
3. **Defaults** — every tunable as a top-level variable with its default. No
magic numbers deep in the script.
4. **Functions** — helpers, including a `usage()` that prints every flag the
script accepts.
5. **Flag parsing** — call `parse_standard_flags "$@"`, then parse
script-specific decision flags from `REMAINING_ARGS`.
6. **Sanity checks** — `require_root`, `require_family <debian|rhel|any>`,
`require_cmd`, and any `require_flag` calls for `--yes` mode.
7. **Main logic** — the work, expressed via `header`, `pass`, `warn`, `fail`,
`info`, and `run`.
---
## The `common.sh` library contract
`common.sh` is the shared library every script sources from
`/usr/local/lib/linux-skills/common.sh`. The full function contract lives in
[`references/common-sh-contract.md`](references/common-sh-contract.md) — read
it before calling a new function. Summary:
### Output
| Function | Purpose |
|---|---|
| `pass "msg"` | Green `[PASS]` line; increments `PASS_COUNT`. |
| `warn "msg"` | Yellow `[WARN]` line; increments `WARN_COUNT`. |
| `fail "msg"` | Red `[FAIL]` line; increments `FAIL_COUNT`. |
| `info "msg"` | Cyan `[INFO]` line; no count. |
| `header "Section"` | Bold section separator. |
| `die "msg" [exit_code]` | Red error to stderr, exit with code (default 1). |
| `log "msg"` | Timestamped line to log file (if `--log`). |
Always use these. Never roll your own `echo -e "\033[31m..."`.
### Guards
| Function | Purpose |
|---|---|
| `require_root` | Exit 1 if not root. |
| `require_family <debian\|rhel\|any>` | Exit 3 if the detected family isn't allowed. Gate a script to one family, or pass `any` for both. Prefer this over the legacy `require_debian`. |
| `require_cmd <cmd>...` | Exit 5 if any command is missing; names the package. |
| `require_flag <NAME>` | Under `--yes`, exit 2 if the named global variable is empty. |
### Interaction (skipped under `--yes`)
| Function | Purpose |
|---|---|
| `confirm "Do X?" [default=N]` | yes/no; default = N. Auto-yes under `--yes` **only** for non-destructive confirms. |
| `confirm_destructive "About to DELETE X"` | Requires typed `yes`, not `y`. Under `--yes`, requires a decision flag — **never** auto-confirms. |
| `prompt "Label" [default] [validator]` | Single-value read with optional default + validator. |
| `select_one "Label" opt1 opt2...` | Numeric menu; returns chosen value. |
### Safe file operations
| Function | Purpose |
|---|---|
| `safe_tempfile [prefix]` | `mktemp` + trap cleanup. Returns path. |
| `safe_tempdir [prefix]` | As above, directory. |
| `atomic_write <target>` | Reads stdin, writes `<target>.new`, `mv` on success. Preserves perms/owner. |
| `backup_file <path>` | Copies to `<path>.bak-YYYYMMDD-HHMMSS`. Prints backup path. |
### Flag parsing
| Function | Purpose |
|---|---|
| `parse_standard_flags "$@"` | Consumes standard flags, sets `DRY_RUN`, `YES`, `LOG_FILE`, `JSON`, `VERBOSE`, `QUIET`. Leaves unknown args in `REMAINING_ARGS`. |
| `run <cmd>...` | Prints the command. In `--dry-run`, prints and skips. |
---
## Standard flags — mandatory on every script
Every script must support these flags via `parse_standard_flags`:
| Flag | Meaning |
|---|---|
| `--help`, `-h` | Print `usage()` and exit 0. Must list every decision flag. |
| `--version` | Print version and exit 0. |
| `--yes`, `-y` | Non-interactive. **Errors** if a required decision flag is missing — never silently defaults. |
| `--dry-run`, `-n` | Print every action, change nothing. |
| `--log[=PATH]` | Tee output to `/var/log/linux-skills/<script>-YYYYMMDD-HHMMSS.log`. |
| `--json` | Machine-readable output (where meaningful). No colors. |
| `--verbose`, `-v` | Extra diagnostics. |
| `--quiet`, `-q` | Errors and final result only. Incompatible with `-v`. |
### The `--yes` contract (non-negotiable)
`--yes` means **"the caller has pre-committed to every decision"**. It does
**not** mean "accept safe defaults." If a script would normally prompt for a
required input and the caller did not supply a flag for it, the script must
abort:
```
ERROR: --yes was passed but --domain is required.
Run `<script> --help` to see required flags.
```
This rule exists because Claude Code invokes scripts non-interactively and
must get exactly the outcome it asked for — silent defaults are a footgun.
---
## Interactive UX rules
When running interactively (no `--yes`), scripts must feel friendly at a
terminal. See [`references/interactive-ux.md`](references/interactive-ux.md)
for the full rule set. Key points:
- **Announce before acting.** Every destructive step prints what it is about
to do, then asks to confirm.
- **Show progress.** Long-running steps use `header` to mark phases.
- **PASS / WARN / FAIL is the output grammar.** Use `pass`, `warn`, `fail`,
`info` — never ad-hoc `echo`.
- **Explain failures.** When a check fails, say *why* in plain English and
point at the remediation (another `sk-*` script, a config file, a man page).
- **Colors are semantic.** Green = good; yellow = watch; red = broken;
cyan = neutral information. Never decorate.
- **Confirm destructive operations with a typed word, not a single letter.**
Use `confirm_destructive`, which requires the user to type `yes`.
- **`Ctrl-C` is a first-class exit path.** The trap installed by `common.sh`
ensures a clean exit. Don't fight it.
- **Help text must be complete.** Every decision flag listed. Examples
included. Fits on one screen where possible.
---
## Safety patterns every script must follow
These are required review rules, but the `sk-lint` wrapper and its pre-commit
hook are not shipped in this checkout. Check them manually and use the
available shell and engine validators before merging.
1. **Source `common.sh`** — never reimplement colors, prompts, traps.
2. **`set -uo pipefail`** — always. **Never** `set -e`.
3. **Quote every variable** — `"$var"`, `"${array[@]}"`, always.
4. **`IFS= read -r`** — every `read`, every time.
5. **Parameter expansion over sed/awk** — `${var##*/}` for basename,
`${var%.*}` for removing a suffix. Faster and safer than subprocessing.
6. **Atomic file edits** — write to `$target.new`, then `mv`. Never `> file`
on anything important. Use `atomic_write` or `backup_file` first.
7. **Safe temp files** — `safe_tempfile`, which auto-registers a cleanup trap.
8. **Validate with `case`, not sprawling regex** — from *Pro Bash*. Easier to
read, easier to extend, easier to debug.
9. **`printf` over `echo`** — `printf '%s\n' "$var"`. `echo`'s behavior varies.
10. **`"$@"` (quoted)** when forwarding args. Unquoted `$@` word-splits.
11. **Exit codes matter** — `0` success, `1` generic failure, `2`
usage/flag error, `3` precondition failed, `4` user aborted, `5`
dependency missing.
12. **Never `eval` untrusted input.** No exceptions.
13. **Validate external configs before reload** — `nginx -t`, `apache2ctl
configtest`, `visudo -c`, `sshd -t`, `named-checkconf`. Every time.
14. **Destructive operations write a timestamped audit line** to
`/var/log/linux-skills/<script>.log` regardless of `--log`.
15. **Every script passes `shellcheck` with zero warnings.** Run
`shellcheck <script>` and `bash -n <script>` before committing.
---
## Handing a script to a user
Applies whenever the user, not Claude, is asked to run a script, typically
because it needs root or a password Claude cannot supply. The command the user
types must be one line and as short as the path allows.
1. **Installed `sk-*` command first.** Check `command -v sk-foo`. If absent, give
`sudo install-skills-bin <skill-name>` once; the user then runs `sudo sk-foo`.
A bare name on `PATH` is the shortest possible path.
2. **One-off collector.** Draft it in the session scratch area, validate it
(`bash -n`, and for a read-only script a grep for mutating verbs), then copy
it to `~/<short-name>.sh`. The user runs `sudo bash ~/<short-name>.sh`. Never
hand over the scratch, temp, or skill-directory path.
3. **No required path arguments.** Default the output to
`$(dirname "$(readlink -f "$0")")/<short-name>.out`, mode 600, owned by
`$SUDO_USER`. Redact password hashes and secrets in that output. Because the
output goes to a file, print one line to the terminal before redirecting
(`writing to <file>`) and one when finished; a script that stays silent looks
like one that failed.
4. **One line, nothing to mangle.** No pipes, `&&` chains, heredocs, or wrapped
paths. In Claude Code, tell the user to type `! ` first and to copy only the
line inside the code block, not the fences.
5. **Root scripts carry a fingerprint and a cleanup line.** Print the first 16
characters of `sha256sum ~/<short-name>.sh` so the user can confirm the file
was not altered after validation, and give
`rm ~/<short-name>.sh ~/<short-name>.out` for afterwards.
Machine-run commands (cloud-init `runcmd`, cron, systemd units) are exempt.
---
## How Claude Code invokes these scripts
When Claude Code is asked to do something that maps to a script in this
toolkit, it must:
1. **Discover** — check `command -v sk-foo` to see if the script is
installed. If not, suggest `sudo install-skills-bin <skill-name>`.
2. **Read help** — run `sk-foo --help` to see the required decision flags.
3. **Pre-commit** — decide every required input up front (domain, user,
port, path, etc.). Never call with `--yes` and hope a default saves the day.
4. **Dry-run first** — when uncertain, run with `--dry-run --yes --<flags>`
to preview.
5. **Invoke** — run with `--yes --log --<flags>`.
6. **Interpret** — parse PASS/WARN/FAIL counts from output; if `--json` is
supported, use it.
If any step of this loop isn't possible (e.g. the script doesn't have the
flag we need), that's a script bug — file it against the inventory, not a
silent workaround.
---
## References
- [`references/script-template.sh`](references/script-template.sh) — the canonical six-section template.
- [`references/common-sh-contract.md`](references/common-sh-contract.md) — full function contract for the shared library.
- [`references/interactive-ux.md`](references/interactive-ux.md) — interactive UX rules in detail.
- [`docs/engine-design/spec.md`](../../docs/engine-design/spec.md) — the binding engine specification.
- [`docs/engine-design/script-inventory.md`](../../docs/engine-design/script-inventory.md) — the curated catalogue.
Pliki w paczce (5)
- SKILL.md 19 KB
- references/agent-operation-contract.md 3 KB
- references/common-sh-contract.md 10 KB
- references/interactive-ux.md 5 KB
- references/script-template.sh 5 KB
Wersje
| Repozytorium | Wynik | Licencja |
|---|---|---|
| Ta strona · peterbamuhigire/linux-skills | 100 | MIT |
| iliaal/ai-skills | 100 | MIT |
| iliaal/whetstone | 100 | MIT |
Migawka bazy z 13.11.2026 · wersja paczki fa8af6233a24 (skrót SHA-256 całej paczki)
Pobrania w ostatnich 30 dniach: 0 · ranking
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 100bash-linux
Podaje wzorce pracy w terminalu Bash i Linux: kluczowe polecenia, potoki, obsługa błędów i skrypty, także na macOS. - 100bash-linux
Podaje wzorce pracy w terminalu Bash i Linux: kluczowe polecenia, potoki, obsługa błędów i skrypty, także na macOS. - 95bash-linux
Podpowiada polecenia terminala Bash i Linux: potoki, obsługę błędów i skrypty, najczęściej na macOS i Linuksie. - 95bash-linux
Podsuwa wzorce pracy w terminalu Bash i Linux: kluczowe polecenia, potoki, obsługę błędów i skrypty na macOS i Linuksie. - 95bash-linux
Podsuwa wzorce pracy w terminalu Bash i Linux: kluczowe polecenia, potoki, obsługę błędów i skrypty na macOS i Linuksie. - 95linux-shell-scripting
Pisze skrypty bash do automatyzacji zadań w Linuksie: monitorowania zasobów, tworzenia kopii zapasowych i zarządzania użytkownikami.