bash-pro について
Bashスクリプトの作成、レビュー、安全性向上を支援する開発スキルです。自動化、CI/CD、運用向けに、安全な引数処理、エラー管理、移植性、テストを扱います。
主な機能
- 01厳格モードとエラー処理
- 02安全な引数解析と入力検証
- 03堅牢なファイル・プロセス操作
- 04BatsテストとShellCheck解析
- 05クロスプラットフォーム対応の指針
- 06ログ、ドキュメント、CI/CDの実践
活用シーン
- 01Bash自動化スクリプトの作成
- 02デプロイ・運用スクリプトの堅牢化
- 03入力やファイル操作の安全性レビュー
- 04スクリプトへのテストとCI検査の追加
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ rmyndharis/ antigravity-skills --skill bash-proインストール後、Claude Code で/bash-proを入力して読み込まれたか確認します。
詳細
このスキルを使用する場合
- 自動化、CI/CD、運用向けの Bash スクリプトを作成またはレビューする場合
- 安全性と移植性のためにシェルスクリプトを強化する場合
このスキルを使用しない場合
- Bash の機能を使わず POSIX のみのシェルが必要な場合
- 複雑なロジックのために高水準言語が必要なタスクの場合
- Windows ネイティブのスクリプト(PowerShell)が必要な場合
手順
- スクリプトの入力、出力、失敗モードを定義します。
- strict モードと安全な引数解析を適用します。
- 防御的なパターンでコアロジックを実装します。
- Bats と ShellCheck でテストとリンティングを追加します。
安全性
- 入力を信頼できないものとして扱い、eval や安全でないグロブを避けます。
- 破壊的な操作の前にドライランモードを優先します。
重点領域
- strict なエラー処理による防御的プログラミング
- POSIX 準拠とクロスプラットフォームの移植性
- 安全な引数解析と入力検証
- 堅牢なファイル操作と一時リソースの管理
- プロセスオーケストレーションとパイプラインの安全性
- 本番グレードのロギングとエラー報告
- Bats フレームワークによる包括的なテスト
- ShellCheck による静的解析と shfmt によるフォーマット
- モダンな Bash 5.x の機能とベストプラクティス
- CI/CD 統合と自動化ワークフロー
アプローチ
- 常に
set -Eeuo pipefailによる strict モードと適切なエラートラップを使用する - 単語分割やグロブの問題を防ぐため、すべての変数展開を引用する
for f in $(ls)のような安全でないパターンよりも、配列と適切な反復を優先する- Bash の条件式には
[[ ]]を使用し、POSIX 準拠が必要な場合は[ ]にフォールバックする getoptsと使用法関数による包括的な引数解析を実装するmktempとクリーンアップトラップで一時ファイルとディレクトリを安全に作成する- 予測可能な出力フォーマットのために
echoよりもprintfを優先する - 可読性のためにバッククォートではなくコマンド置換
$()を使用する - タイムスタンプと設定可能な詳細度を備えた構造化ロギングを実装する
- スクリプトを冪等に設計し、ドライランモードをサポートする
- Bash 4.4+ でのより良いエラー伝播のために
shopt -s inherit_errexitを使用する - スペースでの不要な単語分割を防ぐため
IFS=$'\n\t'を採用する - 必須の環境変数には
: "${VAR:?message}"で入力を検証する - オプション解析を
--で終了し、安全な操作のためにrm -rf -- "$dir"を使用する - 詳細なデバッグのために
set -xのオプトインによる--traceモードをサポートする - 安全なサブプロセスのオーケストレーションのために NUL 境界で
xargs -0を使用する - コマンド出力から安全に配列を生成するために
readarray/mapfileを採用する - 堅牢なスクリプトディレクトリ検出を実装する:
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" - NUL 安全なパターンを使用する:
find -print0 | while IFS= read -r -d '' file; do ...; done
互換性と移植性
- システム間の移植性のために
#!/usr/bin/env bashのシバンを使用する - スクリプト開始時に Bash のバージョンを確認する: Bash 4.4+ の機能には
(( BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 4 )) - 必要な外部コマンドの存在を検証する:
command -v jq &>/dev/null || exit 1 - プラットフォームの違いを検出する:
case "$(uname -s)" in Linux*) ... ;; Darwin*) ... ;; esac - GNU と BSD のツールの違いを扱う(例:
sed -iとsed -i '') - すべてのターゲットプラットフォーム(Linux、macOS、BSD 系)でスクリプトをテストする
- スクリプトのヘッダーコメントに最小バージョン要件を記載する
- プラットフォーム固有の機能にはフォールバック実装を提供する
- 移植性のために、可能な場合は外部コマンドよりも Bash の組み込み機能を使用する
- POSIX 準拠が必要な場合は bashism を避け、Bash 固有の機能を使用する場合は文書化する
可読性と保守性
- スクリプトでは明確さのために長形式のオプションを使用します:
-vではなく--verbose - 一貫した命名を採用します: 関数や変数には snake_case、定数には UPPER_CASE
- 関連する関数を整理するために、コメントブロックによるセクションヘッダーを追加します
- 関数は 50 行以内に保ちます。それより大きい関数はより小さなコンポーネントにリファクタリングします
- 関連する関数を説明的なセクションヘッダーとともにグループ化します
- 目的を説明する説明的な関数名を使用します:
check_fileではなくvalidate_input_file - 自明でないロジックにはインラインコメントを追加し、明らかなことの記述は避けます
- 一貫したインデントを保ちます (2 または 4 スペース、タブとスペースを混在させない)
- 一貫性のために開き中括弧を同じ行に配置します:
function_name() { - 関数内の論理的なブロックを区切るために空行を使用します
- ヘッダーコメントで関数のパラメータと戻り値を文書化します
- マジックナンバーや文字列をスクリプト先頭の名前付き定数に抽出します
安全性とセキュリティのパターン
- 偶発的な変更を防ぐために、定数を
readonlyで宣言します - グローバルスコープを汚染しないように、すべての関数変数に
localキーワードを使用します - 外部コマンドに
timeoutを実装します:timeout 30s curl ...はハングを防ぎます - 操作の前にファイル権限を検証します:
[[ -r "$file" ]] || exit 1 - 可能な場合は一時ファイルの代わりにプロセス置換
<(command)を使用します - コマンドやファイル操作で使用する前にユーザー入力をサニタイズします
- パターンマッチングで数値入力を検証します:
[[ $num =~ ^[0-9]+$ ]] - ユーザー入力に対して
evalを決して使用しないでください。動的なコマンド構築には配列を使用します - 機密性の高い操作には制限的な umask を設定します:
(umask 077; touch "$secure_file") - セキュリティに関連する操作 (認証、権限変更、ファイルアクセス) をログに記録します
- オプションと引数を分離するために
--を使用します:rm -rf -- "$user_input" - 使用前に環境変数を検証します:
: "${REQUIRED_VAR:?not set}" - すべてのセキュリティ上重要な操作の終了コードを明示的に確認します
- 異常終了時でもクリーンアップが確実に行われるように
trapを使用します
パフォーマンスの最適化
- ループ内のサブシェルを避けます:
for i in $(cat file)ではなくwhile readを使用します - 外部コマンドより Bash 組み込みを使用します:
testではなく[[ ]]、sedではなく${var//pattern/replacement} - 繰り返しの単一操作ではなくバッチ操作を行います (例: 複数の式を持つ 1 つの
sed) - コマンド出力から配列を効率的に埋めるには
mapfile/readarrayを使用します - 繰り返しのコマンド置換を避けます。結果を一度変数に格納します
- 計算には
exprではなく算術展開$(( ))を使用します - 整形出力には
echoよりprintfを優先します (より高速で信頼性が高い) - 繰り返しの grep ではなく連想配列をルックアップに使用します
- 大きなファイルはファイル全体をメモリに読み込むのではなく、行ごとに処理します
- 操作が独立している場合は並列処理に
xargs -Pを使用します
ドキュメントの標準
- 使用方法、オプション、例を表示する
--helpおよび-hフラグを実装します - スクリプトのバージョンと著作権情報を表示する
--versionフラグを提供します - 一般的なユースケースの使用例をヘルプ出力に含めます
- すべてのコマンドラインオプションをその目的の説明とともに文書化します
- 使用方法のメッセージで必須引数と任意引数を明確に区別して示します
- 終了コードを文書化します: 成功は 0、一般的なエラーは 1、特定の失敗には特定のコード
- 必要なコマンドとバージョンを列挙する前提条件セクションを含めます
- スクリプトの目的、作者、変更日を含むヘッダーコメントブロックを追加します
- スクリプトが使用または要求する環境変数を文書化します
- 一般的な問題に対するトラブルシューティングセクションをヘルプに提供します
- 特別なコメント形式から
shdocでドキュメントを生成します - システム統合のために
shellmanを使用して man ページを作成します - 複雑なスクリプトには Mermaid や GraphViz を使用したアーキテクチャ図を含めます
モダンな Bash の機能 (5.x)
- Bash 5.0: 連想配列の改善、
${var@U}による大文字変換、${var@L}による小文字変換 - Bash 5.1: 強化された
${parameter@operator}変換、互換性のためのcompatshopt オプション - Bash 5.2:
varredir_closeオプション、改善されたexecのエラー処理、EPOCHREALTIMEのマイクロ秒精度 - モダンな機能を使用する前にバージョンを確認してください:
[[ ${BASH_VERSINFO[0]} -ge 5 && ${BASH_VERSINFO[1]} -ge 2 ]] - シェル引用された出力には
${parameter@Q}を使用してください (Bash 4.4+) - エスケープシーケンスの展開には
${parameter@E}を使用してください (Bash 4.4+) - プロンプト展開には
${parameter@P}を使用してください (Bash 4.4+) - 代入形式には
${parameter@A}を使用してください (Bash 4.4+) - 任意のバックグラウンドジョブを待機するには
wait -nを活用してください (Bash 4.3+) - カスタム区切り文字には
mapfile -d delimを使用してください (Bash 4.4+)
CI/CD 統合
- GitHub Actions: インライン注釈には
shellcheck-problem-matchersを使用してください - Pre-commit フック:
shellcheck、shfmt、checkbashismsを使用して.pre-commit-config.yamlを設定してください - マトリックステスト: Linux と macOS 上で Bash 4.4、5.0、5.1、5.2 をまたいでテストしてください
- コンテナテスト: 再現可能なテストには公式の bash:5.2 Docker イメージを使用してください
- CodeQL: セキュリティ脆弱性のためにシェルスクリプトのスキャンを有効にしてください
- Actionlint: シェルスクリプトを使用する GitHub Actions ワークフローファイルを検証してください
- 自動リリース: バージョンにタグを付け、変更履歴を自動生成してください
- カバレッジレポート: テストカバレッジを追跡し、リグレッションで失敗させてください
- ワークフローの例:
shellcheck *.sh && shfmt -d *.sh && bats test/
セキュリティスキャンと堅牢化
- SAST: シェル固有の脆弱性に対するカスタムルールで Semgrep を統合してください
- シークレット検出: 認証情報の漏洩を防ぐために
gitleaksまたはtrufflehogを使用してください - サプライチェーン: 読み込む外部スクリプトのチェックサムを検証してください
- サンドボックス化: 信頼できないスクリプトは権限を制限したコンテナ内で実行してください
- SBOM: コンプライアンスのために依存関係と外部ツールを文書化してください
- セキュリティリンティング: セキュリティに焦点を当てたルールを有効にして ShellCheck を使用してください
- 権限分析: 不要な root/sudo 要件がないかスクリプトを監査してください
- 入力のサニタイズ: すべての外部入力を許可リストに対して検証してください
- 監査ログ: セキュリティに関連するすべての操作を syslog に記録してください
- コンテナセキュリティ: スクリプト実行環境の脆弱性をスキャンしてください
可観測性とログ
- 構造化ログ: ログ集約システム向けに JSON を出力してください
- ログレベル: 設定可能な詳細度で DEBUG、INFO、WARN、ERROR を実装してください
- Syslog 統合: システムログ統合には
loggerコマンドを使用してください - 分散トレーシング: 複数スクリプトのワークフローを関連付けるためにトレース ID を追加してください
- メトリクスのエクスポート: 監視のために Prometheus 形式のメトリクスを出力してください
- エラーコンテキスト: エラーログにスタックトレースや環境情報を含めてください
- ログローテーション: 長時間実行されるスクリプトのためにログファイルのローテーションを設定してください
- パフォーマンスメトリクス: 実行時間、リソース使用量、外部呼び出しのレイテンシを追跡してください
- 例:
log_info() { logger -t "$SCRIPT_NAME" -p user.info "$*"; echo "[INFO] $*" >&2; }
品質チェックリスト
- スクリプトは最小限の抑制で ShellCheck 静的解析を通過すること
- コードは標準オプションを使用して shfmt で一貫してフォーマットされていること
- エッジケースを含む Bats による包括的なテストカバレッジがあること
- すべての変数展開が適切に引用されていること
- エラー処理がすべての失敗モードを意味のあるメッセージでカバーしていること
- 一時リソースが EXIT トラップで適切にクリーンアップされること
- スクリプトが
--helpをサポートし、明確な使用方法を提供していること - 入力検証がインジェクション攻撃を防ぎ、エッジケースを処理していること
- スクリプトが対象プラットフォーム (Linux、macOS) 間で移植可能であること
- パフォーマンスが想定されるワークロードとデータサイズに対して十分であること
出力
- 防御的プログラミング手法を採用した本番環境対応の Bash スクリプト
- bats-core または shellspec を使用した、TAP 出力対応の包括的なテストスイート
- 自動テストのための CI/CD パイプライン構成(GitHub Actions、GitLab CI)
- shdoc で生成するドキュメントと shellman による man ページ
- 再利用可能なライブラリ関数と依存関係管理を備えた構造化されたプロジェクトレイアウト
- 静的解析の構成ファイル(.shellcheckrc、.shfmt.toml、.editorconfig)
- 重要なワークフロー向けのパフォーマンスベンチマークとプロファイリングレポート
- SAST、シークレットスキャン、脆弱性レポートによるセキュリティレビュー
- トレースモード、構造化ログ、可観測性を備えたデバッグユーティリティ
- Bash 3→5 へのアップグレードとレガシー近代化のための移行ガイド
- パッケージ配布構成(Homebrew フォーミュラ、deb/rpm スペック)
- 再現可能な実行環境のためのコンテナイメージ
必須ツール
静的解析とフォーマット
- ShellCheck:
enable=allとexternal-sources=trueを構成した静的解析ツール - shfmt: 標準構成(
-i 2 -ci -bn -sr -kp)のシェルスクリプトフォーマッター - checkbashisms: 移植性分析のために bash 固有の構文を検出します
- Semgrep: シェル固有のセキュリティ問題に対するカスタムルールを用いた SAST
- CodeQL: GitHub によるシェルスクリプトのセキュリティスキャン
テストフレームワーク
- bats-core: モダンな機能と活発な開発を備えた Bats のメンテナンスされたフォーク
- shellspec: 豊富なアサーションとモックを備えた BDD スタイルのテストフレームワーク
- shunit2: シェルスクリプト向けの xUnit スタイルのテストフレームワーク
- bashing: モックサポートとテスト分離を備えたテストフレームワーク
モダンな開発ツール
- bashly: コマンドラインアプリケーションを構築するための CLI フレームワークジェネレーター
- basher: 依存関係管理のための Bash パッケージマネージャー
- bpkg: npm に似たインターフェースを持つ代替の bash パッケージマネージャー
- shdoc: シェルスクリプトのコメントから markdown ドキュメントを生成します
- shellman: シェルスクリプトから man ページを生成します
CI/CD と自動化
- pre-commit: 多言語対応の pre-commit フックフレームワーク
- actionlint: GitHub Actions ワークフローのリンター
- gitleaks: 認証情報の漏洩を防ぐシークレットスキャン
- Makefile: lint、format、test、release の各ワークフローの自動化
避けるべきよくある落とし穴
for f in $(ls ...)は単語分割やグロブのバグを引き起こします(find -print0 | while IFS= read -r -d '' f; do ...; doneを使用してください)- クォートされていない変数展開は予期しない動作を引き起こします
- 複雑なフローで適切なエラートラップなしに
set -eに依存すること - データ出力に
echoを使用すること(信頼性のためにprintfを優先してください) - 一時ファイルやディレクトリのクリーンアップトラップの欠如
- 安全でない配列の設定(コマンド置換ではなく
readarray/mapfileを使用してください) - バイナリセーフなファイル処理の無視(ファイル名には常に NUL 区切りを検討してください)
依存関係管理
- パッケージマネージャー: シェルスクリプトの依存関係をインストールするには
basherまたはbpkgを使用します - ベンダリング: 再現可能なビルドのために依存関係をプロジェクトにコピーします
- ロックファイル: 使用する依存関係の正確なバージョンを記録します
- チェックサム検証: 外部スクリプトを読み込む際にその完全性を検証します
- バージョンの固定: 破壊的な変更を防ぐために依存関係を特定のバージョンに固定します
- 依存関係の分離: 異なる依存関係セットごとに別々のディレクトリを使用します
- 更新の自動化: Dependabot または Renovate で依存関係の更新を自動化します
- セキュリティスキャン: 依存関係に既知の脆弱性がないかスキャンします
- 例:
basher install username/repo@versionまたはbpkg install username/repo -g
高度なテクニック
- エラーコンテキスト:デバッグには
trap 'echo "Error at line $LINENO: exit $?" >&2' ERRを使用します - 一時ファイルの安全な処理:
trap 'rm -rf "$tmpdir"' EXIT; tmpdir=$(mktemp -d) - バージョン確認:最新の機能を使用する前に
(( BASH_VERSINFO[0] >= 5 ))を確認します - バイナリセーフな配列:
readarray -d '' files < <(find . -print0) - 関数からの値の返却:関数から複雑なデータを返すには
declare -g resultを使用します - 連想配列:複雑なデータ構造には
declare -A config=([host]="localhost" [port]="8080")を使用します - パラメーター展開:
${filename%.sh}は拡張子を削除し、${path##*/}はベース名を取得し、${text//old/new}はすべて置換します - シグナル処理:正常なシャットダウンには
trap cleanup_function SIGHUP SIGINT SIGTERMを使用します - コマンドのグループ化:
{ cmd1; cmd2; } > output.logはリダイレクトを共有し、( cd dir && cmd )は分離のためにサブシェルを使用します - コプロセス:双方向パイプには
coproc proc { cmd; }; echo "data" >&"${proc[1]}"; read -u "${proc[0]}" resultを使用します - ヒアドキュメント:
cat <<-'EOF'は先頭のタブを削除し、引用符は展開を防ぎます - プロセス管理:バックグラウンドジョブの終了を待つには
wait $pidを、バックグラウンドの PID を一覧表示するにはjobs -pを使用します - 条件付き実行:
cmd1 && cmd2はcmd1が成功した場合にのみcmd2を実行し、cmd1 || cmd2はcmd1が失敗した場合にcmd2を実行します - ブレース展開:
touch file{1..10}.txtは複数のファイルを効率よく作成します - 名前参照変数:
declare -n ref=varnameは別の変数への参照を作成します(Bash 4.3 以降) - エラートラップの強化:包括的なエラー処理には
set -Eeuo pipefail; shopt -s inherit_errexitを使用します - 並列実行:CPU コア数を使った並列処理には
xargs -P $(nproc) -n 1 commandを使用します - 構造化出力:JSON の生成には
jq -n --arg key "$value" '{key: $key}'を使用します - パフォーマンスのプロファイリング:詳細なリソース使用状況には
time -vを、カスタムの計測にはTIMEFORMATを使用します
参考資料と詳細情報
スタイルガイドとベストプラクティス
- Google Shell Style Guide - クォート、配列、シェルを使用する場面を網羅した包括的なスタイルガイド
- Bash Pitfalls - よくある Bash の誤りとその回避方法をまとめた一覧
- Bash Hackers Wiki - 包括的な Bash のドキュメントと高度なテクニック
- Defensive BASH Programming - 最新の防御的プログラミングのパターン
ツールとフレームワーク
- ShellCheck - 静的解析ツールと充実した Wiki ドキュメント
- shfmt - 詳細なフラグのドキュメントを備えたシェルスクリプトフォーマッター
- bats-core - メンテナンスが継続されている Bash テストフレームワーク
- shellspec - シェルスクリプト向けの BDD スタイルのテストフレームワーク
- bashly - 最新の Bash CLI フレームワークジェネレーター
- shdoc - シェルスクリプト向けのドキュメントジェネレーター
セキュリティと高度なトピック
- Bash Security Best Practices - セキュリティを重視したシェルスクリプトのパターン
- Awesome Bash - Bash のリソースとツールを厳選した一覧
- Pure Bash Bible - 外部コマンドを使わない Bash の代替手段集
コメント
Markdown 対応