writing-bash

star 0

Rules for writing bash scripts and shell functions.

h2suzuki By h2suzuki schedule Updated 6/3/2026

name: writing-bash description: Rules for writing bash scripts and shell functions. when_to_use: TRIGGER when editing or creating a .sh file, or when writing a shell script / bash function / multi-line shell pipeline. SKIP for Python, Ruby, fish, or other non-bash scripts.

Bash Writing Rules

Rules

  • パイプを避けられる時は避ける。

    • grep regex | awk '{ do-something }'awk '/regex/ { do-something }'
    • echo "$var" | cmdcmd <<< "$var"(here-string; サブシェルを生成しない)
  • プロセス生成はなるべく避ける。

    • jq 式の中で現在時刻が必要なら date +%s を spawn せず jq 組み込みの now を使う
    • cp src dst && chmod 0755 dstinstall -m 0755 src dst(1 プロセスで完結)
    • var="$(cat)" / var="$(cat file)" は原則禁止(cat を spawn)。ファイルは var="$(< file)"、通常の stdin は var="$(</dev/stdin)"(bash 組み込み・fork なし)
      • 例外: hook の stdin は socket$(</dev/stdin)/proc/self/fd/0開き直すため socket では 0 byte になる(Claude Code は hook payload を socket 渡し)。既に開いている fd 0 を直読する var="$(cat)"(または IFS= read -r -d '' var)を使う
    • slurp した変数を jq 等へ渡すときは、再び cat せず here-string cmd <<<"$var"(またはリダイレクト)で渡す
    • 同じ入力から複数値を取るとき jq を複数回呼ばない。1 回の jq -r '.a, .b'(改行区切り出力)を { read -r a; read -r b; } で受ける
  • 実行されるスクリプトには exec bit を必ず立てる。 shebang 付きで bare command(./x / hook の command field / $PATH 経由)として起動されるファイルは mode 644 だと Permission denied で exec 不能。

    • 作成したら chmod +x。 git 管理下なら git ls-files -s <path>100755 か確認(100644 は実行不可)
    • cp / cp -r / install-m 無し)は source の mode をそのまま deploy 先へ複製する。 deploy script が -m で上書きしない限り、 source の mode 誤りは deploy 先の exec 失敗に直結する
  • プログラム名をハードコードしない。

    • コマンドパスを絶対パスで書かず PATH に任せる(/usr/bin/jqjq
    • スクリプト自身の名前はリテラルではなく $(basename "$0") を使う
  • core-utils 以外のコマンドは存在確認してから使う。 command -v foo >/dev/null 2>&1 || { echo "foo not found"; exit 1; } あるいは任意実行なら if command -v foo >/dev/null 2>&1; then foo ...; fi

  • shellcheck が使えるなら使う。 スクリプトを書いたら shellcheck --enable=deprecate-which script.sh で検証する(deprecate-which=SC2230 を上乗せ: which は Debian trixie で削除・非推奨ゆえ存在確認は command -v を使う)。 設定ファイルは置かず CLI 引数で運用。

  • shellcheck の抑制(適用判定は writing-code「指摘は修正が基本、 抑制は例外」): 対象行の直前に # shellcheck disable=SC2086(code 指定)を置く。 shebang 直後に置くと file 全体に効く。 誤検知が確実 / 逆に読みにくくなる / 正当な理由がある時のみ、 理由を添えて使う

  • obsolete commands を使わない(代替を使う)。 未保守ツールは bug fix が来ず、 新しめ distro / 最小 image では存在しないことがある。 スクリプトでは保守された標準の代替を使う:

    避ける 代替 理由
    which command -v 非 POSIX・Debian trixie で削除(shellcheck SC2230 が検出)
    egrep grep -E deprecated
    fgrep grep -F deprecated
    ifconfig ip addr net-tools 未保守 → iproute2
    route ip route net-tools 未保守 → iproute2
    netstat ss net-tools 未保守 → iproute2

    deprecation は環境で異なるので、 断定前に現行 doc で確認する(出典: Red Hat "Deprecated Linux command replacements")。 なお nslookupobsolete ではない: 現行 man page (bind9-dnsutils) に非推奨記述はなく、 dig と同一 package。 script では出力が扱いやすい dig が好まれるが、 これは好みで deprecation ではない。

Install via CLI
npx skills add https://github.com/h2suzuki/terminal-configs --skill writing-bash
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator