Agent Skills by ALSEL
Anthropic ClaudeDevOps・インフラ⭐ リポ 0品質スコア 50/100

bash-master

あらゆるプラットフォームに対応したbash/シェルスクリプトの専門スキルです。シェルスクリプトの作成・レビュー・デバッグ、システム自動化、DevOps/CI/CDスクリプト、ビルド・デプロイ自動化など幅広い用途で自動的に起動します。Google Shell Style GuideへのコンプライアンスやShellCheckによる検証、Linux/macOS/Windows/コンテナ環境でのクロスプラットフォーム対応、セキュリティ強化、エラーハンドリング、BATSを用いたテストなどを提供し、本番環境でも通用するプロフェッショナルなスクリプトを生成します。

description の原文を見る

Expert bash/shell scripting system across ALL platforms. PROACTIVELY activate for: (1) ANY bash/shell script task, (2) System automation, (3) DevOps/CI/CD scripts, (4) Build/deployment automation, (5) Script review/debugging, (6) Converting commands to scripts. Provides: Google Shell Style Guide compliance, ShellCheck validation, cross-platform compatibility (Linux/macOS/Windows/containers), POSIX compliance, security hardening, error handling, performance optimization, testing with BATS, and production-ready patterns. Ensures professional-grade, secure, portable scripts every time.

SKILL.md 本文

Bashスクリプティング習熟度

🚨 重大なガイドライン

Windowsファイルパス要件

必須: Windowsでファイルパスを使用する場合は常にバックスラッシュを使用してください

EditまたはWriteツールをWindowsで使用する場合は、ファイルパスでフォワードスラッシュ(/)ではなく、バックスラッシュ(\)を使用する必要があります。

例:

  • ❌ 間違い: D:/repos/project/file.tsx
  • ✅ 正しい: D:\repos\project\file.tsx

これは以下に適用されます:

  • Editツールのfile_pathパラメータ
  • Writeツールのfile_pathパラメータ
  • Windowsシステム上のすべてのファイル操作

ドキュメンテーションガイドライン

ユーザーから明示的にリクエストされない限り、新しいドキュメントファイルを作成しないでください。

  • 優先順位: 新しいドキュメントの作成ではなく、既存のREADME.mdファイルの更新
  • リポジトリの整理: リポジトリルートを清潔に保つ - ユーザーが明示的にリクエストしない限りREADME.mdのみ
  • スタイル: ドキュメントは簡潔で直接的、プロフェッショナルである必要があります - AI生成的なトーンを避けてください
  • ユーザー設定: ユーザーが特にドキュメント作成をリクエストしたときのみ追加の.mdファイルを作成してください

すべてのプラットフォーム上でプロフェッショナル、ポータブル、保守可能なbashスクリプトを作成するための包括的なガイド。


TL;DR クイックリファレンス

すべてのbashスクリプト向けの必須チェックリスト:

#!/usr/bin/env bash
set -euo pipefail  # エラー時に終了、未定義変数、パイプ失敗時に終了
IFS=$'\n\t'        # 安全な単語分割

# 使用: デプロイ前にshellcheckでスクリプトをチェック
# 本番環境前にターゲットプラットフォームでテスト

プラットフォーム互換性クイックチェック:

# Linux/macOS: ✓ 完全なbash機能
# Git Bash (Windows): ✓ ほとんどの機能、✗ いくつかのシステムコール
# コンテナ: ✓ ベースイメージに依存
# POSIXモード: /bin/shを使用しbashismを避ける

概要

このスキルは、あらゆるスクリプティングタスク向けのエキスパートbash/シェルスクリプティング知識を提供し、すべてのプラットフォーム間でプロフェッショナルグレードの品質を保証します。

このスキルを使用する必要があります:

  • ✅ あらゆるbash/シェルスクリプト作成または変更
  • ✅ システム自動化とツーリング
  • ✅ DevOps/CI/CDパイプラインスクリプト
  • ✅ ビルドおよびデプロイメント自動化
  • ✅ スクリプトレビュー、デバッグ、または最適化
  • ✅ 手動コマンドの自動化スクリプトへの変換
  • ✅ クロスプラットフォームスクリプト互換性

このスキルが提供するもの:

  • Google Shell Style Guide準拠 - 業界標準のフォーマットとパターン
  • ShellCheck検証 - 一般的な問題の自動検出
  • クロスプラットフォーム互換性 - Linux、macOS、Windows (Git Bash/WSL)、コンテナ
  • POSIX準拠 - すべての場所で動作するポータブルスクリプト
  • セキュリティ強化 - 入力検証、インジェクション防止、権限管理
  • エラーハンドリング - 堅牢なset -euo pipefail、trapハンドラ、終了コード
  • パフォーマンス最適化 - 効率的なパターン、アンチパターンを避ける
  • BATSでのテスト - ユニットテスト、統合テスト、CI/CD統合
  • デバッグ技法 - ロギング、トラブルシューティング、プロファイリング
  • 本番環境対応パターン - 実際の使用向けのテンプレートとベストプラクティス

このスキルは以下の場合に自動的にアクティベートされます:

  • タスク内で「bash」、「shell」、「script」の言及
  • システム自動化リクエスト
  • DevOps/CI/CDタスク
  • ビルド/デプロイメント自動化
  • コマンドラインツール作成

コア原則

1. 安全性優先

スクリプトは常に安全設定で始める:

#!/usr/bin/env bash

# 早期失敗
set -e          # エラー時に終了
set -u          # 未定義変数時に終了
set -o pipefail # パイプ失敗時に終了
set -E          # ERR trapを関数が継承

# オプション:
# set -x        # デバッグモード(実行前にコマンド表示)
# set -C        # リダイレクトでのファイル上書き防止

# 安全な単語分割
IFS=$'\n\t'

# スクリプトメタデータ
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"

重要な理由:

  • set -e: カスケード失敗を防止
  • set -u: 変数名のタイプミスをキャッチ
  • set -o pipefail: パイプの中間の失敗をキャッチ
  • IFS=$'\n\t': スペースでの単語分割を防止 (セキュリティ問題)

2. POSIX互換性 vs Bash機能

どちらを使用するかを知る:

# POSIX準拠 (シェル間でポータブル)
#!/bin/sh
# 使用: [ ] テスト、配列なし、[[ ]] なし、<(プロセス置換) なし

# Bash固有 (モダン機能、より明確な構文)
#!/usr/bin/env bash
# 使用: [[ ]]、配列、連想配列、<()、プロセス置換

意思決定マトリックス:

  • あらゆるUNIXシステムで実行する必要がある → #!/bin/shとPOSIXのみ使用
  • 環境を制御している (モダンLinux/macOS) → #!/usr/bin/env bash使用
  • 高度な機能が必要 (配列、正規表現) → #!/usr/bin/env bash使用

3. クォーティングルール (重大)

# 変数は常にクォートして単語分割とグロッビングを防止
bad_cmd=$file_path          # ✗ 間違い - 単語分割
good_cmd="$file_path"       # ✓ 正しい

# 配列: 拡張をクォート
files=("file 1.txt" "file 2.txt")
process "${files[@]}"       # ✓ 正しい - 各要素がクォート
process "${files[*]}"       # ✗ 間違い - すべての要素が1つの文字列

# コマンド置換: 結果をクォート
result="$(command)"         # ✓ 正しい
result=$(command)           # ✗ 間違い (単語分割が必要な場合を除く)

# 例外: 単語分割が必要な場合
# shellcheck disable=SC2086
flags="-v -x -z"
command $flags              # 意図的な単語分割

4. ShellCheckを使用

デプロイ前に常にShellCheckを実行:

# インストール
# Ubuntu/Debian: apt-get install shellcheck
# macOS: brew install shellcheck
# Windows: scoop install shellcheck

# 使用方法
shellcheck your_script.sh
shellcheck -x your_script.sh  # ソースステートメントを追従

# CI/CD内
find . -name "*.sh" -exec shellcheck {} +

ShellCheckがキャッチするもの:

  • クォーティング問題
  • POSIXスクリプト内のbashism
  • 一般的なロジックエラー
  • セキュリティ脆弱性
  • パフォーマンスアンチパターン

プラットフォーム固有の考慮事項

Windows (Git Bash) パス変換 - 重大

重要な知識: Git Bash/MINGWは、Unixスタイルのパスを自動的にWindowsパスに変換します。これはWindowス上でのクロスプラットフォームスクリプティングエラーの最も一般的な原因です。

完全ガイド: references/windows-git-bash-paths.mdを参照してください。

クイックリファレンス:

# 自動変換が発生する対象:
/foo → C:/Program Files/Git/usr/foo
--dir=/tmp → --dir=C:/msys64/tmp

# 必要な場合は変換を無効化
MSYS_NO_PATHCONV=1 command /path/that/should/not/convert

# cygpathを使用した手動変換
unix_path=$(cygpath -u "C:\Windows\System32")  # WindowsからUnix
win_path=$(cygpath -w "/c/Users/username")        # UnixからWindows

# シェル検出 (最速の方法)
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "mingw"* ]]; then
    echo "Git Bash検出"
    # パス変換を使用
fi

# または$MSYSTEM変数をチェック (Git Bash/MSYS2固有)
case "${MSYSTEM:-}" in
    MINGW64|MINGW32|MSYS)
        echo "MSYS2/Git Bash環境: $MSYSTEM"
        ;;
esac

一般的な問題:

# 問題: フラグがパスに変換
command /e /s  # /eがC:/Program Files/Git/eになる

# 解決策: ダブルスラッシュまたはダッシュを使用
command //e //s  # または: command -e -s

# 問題: パス内のスペース
cd C:\Program Files\Git  # 失敗

# 解決策: パスをクォート
cd "C:\Program Files\Git"  # または: cd /c/Program\ Files/Git

Linux

ほとんどのbashスクリプト向けの主要なターゲット:

# Linux固有の機能が利用可能
/proc ファイルシステム
systemd統合
Linux固有のコマンド (apt, yum, systemctl)

# Linuxをチェック
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    # Linux固有のコード
fi

macOS

BSD基盤のユーティリティ (GNUと異なる):

# macOSの違い
sed -i ''                    # macOSは空の文字列が必要
sed -i                       # Linuxは不要

# GNU版用にggrep、gsedなどを使用
if command -v gsed &> /dev/null; then
    SED=gsed
else
    SED=sed
fi

# macOSをチェック
if [[ "$OSTYPE" == "darwin"* ]]; then
    # macOS固有のコード
fi

Windows (Git Bash / WSL)

Git Bashの制限:

# Git Bashで利用可能:
- ほとんどのコアユーティリティ
- ファイル操作
- プロセス管理 (制限付き)

# 利用不可:
- systemd
- いくつかのシグナル (SIGHUPの動作が異なる)
- /proc ファイルシステム
- ネイティブWindowsパス処理の問題

# パス処理
# Git BashはUnixパスを使用: /c/Users/...
# 必要に応じて変換:
winpath=$(cygpath -w "$unixpath")  # Unix → Windows
unixpath=$(cygpath -u "$winpath")  # Windows → Unix

# Git Bashをチェック
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]]; then
    # Git Bash / Cygwinコード
fi

WSL (Windows Subsystem for Linux):

# WSLは本質的にLinuxですが:
# - Windowsファイルシステムに/mnt/c/でアクセス可能
# - いくつかのシステムコールの動作が異なる
# - ネットワーク設定が異なる

# WSLをチェック
if grep -qi microsoft /proc/version 2>/dev/null; then
    # WSL固有のコード
fi

コンテナ (Docker/Kubernetes)

コンテナ対応スクリプティング:

# 最小限のベースイメージはbashを持たない場合があります
# #!/bin/shを使用するか、bashを明示的にインストール

# コンテナ検出
if [ -f /.dockerenv ] || grep -q docker /proc/1/cgroup 2>/dev/null; then
    # Dockerで実行中
fi

# Kubernetes検出
if [ -n "$KUBERNETES_SERVICE_HOST" ]; then
    # Kubernetesで実行中
fi

# ベストプラクティス:
# - 依存関係を最小化
# - 絶対パスまたはPATHを使用
# - ユーザー/グループの存在を想定しない
# - シグナルを適切に処理 (PID 1の問題)

クロスプラットフォームテンプレート

#!/usr/bin/env bash
set -euo pipefail

# プラットフォーム検出
detect_platform() {
    case "$OSTYPE" in
        linux-gnu*)   echo "linux" ;;
        darwin*)      echo "macos" ;;
        msys*|cygwin*) echo "windows" ;;
        *)            echo "unknown" ;;
    esac
}

PLATFORM=$(detect_platform)

# プラットフォーム固有のパス
case "$PLATFORM" in
    linux)
        SED=sed
        ;;
    macos)
        SED=$(command -v gsed || echo sed)
        ;;
    windows)
        # Git Bash固有
        ;;
esac

ベストプラクティス

関数設計

# 適切な関数構造
function_name() {
    # 1. ローカル変数を最初に
    local arg1="$1"
    local arg2="${2:-default_value}"
    local result=""

    # 2. 入力検証
    if [[ -z "$arg1" ]]; then
        echo "Error: arg1は必須です" >&2
        return 1
    fi

    # 3. メインロジック
    result=$(some_operation "$arg1" "$arg2")

    # 4. 出力/リターン
    echo "$result"
    return 0
}

# 関数を使用し、スクリプト内スクリプトは使用しない
# メリット: テスト可能性、再利用性、名前空間化

変数命名

# 定数: UPPER_CASE
readonly MAX_RETRIES=3
readonly CONFIG_FILE="/etc/app/config.conf"

# グローバル変数: UPPER_CASEまたはlower_case (一貫性を保つ)
GLOBAL_STATE="initialized"

# ローカル変数: lower_case
local user_name="john"
local file_count=0

# 環境変数: UPPER_CASE (慣例)
export DATABASE_URL="postgres://..."

# 可能な場合はreadonly
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

エラーハンドリング

# 方法1: 明示的に終了コードをチェック
if ! command_that_might_fail; then
    echo "Error: コマンドが失敗しました" >&2
    return 1
fi

# 方法2: 代替アクション用に||を使用
command_that_might_fail || {
    echo "Error: コマンドが失敗しました" >&2
    return 1
}

# 方法3: クリーンアップ用のTrap
cleanup() {
    local exit_code=$?
    # クリーンアップ操作
    rm -f "$TEMP_FILE"
    exit "$exit_code"
}
trap cleanup EXIT

# 方法4: カスタムエラーハンドラ
error_exit() {
    local message="$1"
    local code="${2:-1}"
    echo "Error: $message" >&2
    exit "$code"
}

# 使用方法
[[ -f "$config_file" ]] || error_exit "設定ファイルが見つかりません: $config_file"

入力検証

validate_input() {
    local input="$1"

    # 空かどうかチェック
    if [[ -z "$input" ]]; then
        echo "Error: 入力は空にできません" >&2
        return 1
    fi

    # フォーマットチェック (例: 英数字のみ)
    if [[ ! "$input" =~ ^[a-zA-Z0-9_-]+$ ]]; then
        echo "Error: 入力に無効な文字が含まれています" >&2
        return 1
    fi

    # 長さをチェック
    if [[ ${#input} -gt 255 ]]; then
        echo "Error: 入力が長すぎます (最大255文字)" >&2
        return 1
    fi

    return 0
}

# 使用前に検証
read -r user_input
if validate_input "$user_input"; then
    process "$user_input"
fi

引数解析

# シンプルな引数解析
usage() {
    cat <<EOF
使用方法: $SCRIPT_NAME [OPTIONS] <command>

オプション:
    -h, --help          このヘルプを表示
    -v, --verbose       詳細出力
    -f, --file FILE     入力ファイル
    -o, --output DIR    出力ディレクトリ

コマンド:
    build               プロジェクトをビルド
    test                テストを実行
EOF
}

main() {
    local verbose=false
    local input_file=""
    local output_dir="."
    local command=""

    # 引数を解析
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -h|--help)
                usage
                exit 0
                ;;
            -v|--verbose)
                verbose=true
                shift
                ;;
            -f|--file)
                input_file="$2"
                shift 2
                ;;
            -o|--output)
                output_dir="$2"
                shift 2
                ;;
            -*)
                echo "Error: 不明なオプション: $1" >&2
                usage >&2
                exit 1
                ;;
            *)
                command="$1"
                shift
                break
                ;;
        esac
    done

    # 必須引数を検証
    if [[ -z "$command" ]]; then
        echo "Error: コマンドが必須です" >&2
        usage >&2
        exit 1
    fi

    # コマンドを実行
    case "$command" in
        build) do_build ;;
        test)  do_test ;;
        *)
            echo "Error: 不明なコマンド: $command" >&2
            usage >&2
            exit 1
            ;;
    esac
}

main "$@"

ロギング

# ロギングレベル
readonly LOG_LEVEL_DEBUG=0
readonly LOG_LEVEL_INFO=1
readonly LOG_LEVEL_WARN=2
readonly LOG_LEVEL_ERROR=3

# 現在のログレベル
LOG_LEVEL=${LOG_LEVEL:-$LOG_LEVEL_INFO}

log_debug() { [[ $LOG_LEVEL -le $LOG_LEVEL_DEBUG ]] && echo "[DEBUG] $*" >&2; }
log_info()  { [[ $LOG_LEVEL -le $LOG_LEVEL_INFO  ]] && echo "[INFO]  $*" >&2; }
log_warn()  { [[ $LOG_LEVEL -le $LOG_LEVEL_WARN  ]] && echo "[WARN]  $*" >&2; }
log_error() { [[ $LOG_LEVEL -le $LOG_LEVEL_ERROR ]] && echo "[ERROR] $*" >&2; }

# タイムスタンプ付き
log_with_timestamp() {
    local level="$1"
    shift
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$level] $*" >&2
}

# 使用方法
log_info "プロセスを開始"
log_error "データベースへの接続に失敗"

セキュリティベストプラクティス

コマンドインジェクション防止

# eval をユーザー入力で使用しない
# ✗ 間違い - 危険
eval "$user_input"

# ユーザー入力から動的な変数名を使用しない
# ✗ 間違い - 危険
eval "var_$user_input=value"

# ユーザー入力をコマンドに連結しない
# ✗ 間違い - 危険
grep "$user_pattern" file.txt  # パターンが-eフラグを含む場合、インジェクション可能

# ✓ 正しい - 配列を使用
grep_args=("$user_pattern" "file.txt")
grep "${grep_args[@]}"

# ✓ 正しい - --を使用してオプションと引数を分離
grep -- "$user_pattern" file.txt

パストラバーサル防止

# ファイルパスをサニタイズ
sanitize_path() {
    local path="$1"

    # .. コンポーネントを削除
    path="${path//..\/}"
    path="${path//\/..\//}"

    # リーディング/を削除
    path="${path#/}"

    echo "$path"
}

# パスが許可されたディレクトリ内にあることを検証
is_safe_path() {
    local file_path="$1"
    local base_dir="$2"

    # 絶対パスに解決
    local real_path
    real_path=$(readlink -f "$file_path" 2>/dev/null) || return 1
    local real_base
    real_base=$(readlink -f "$base_dir" 2>/dev/null) || return 1

    # パスがベースディレクトリで始まるかチェック
    [[ "$real_path" == "$real_base"/* ]]
}

# 使用方法
if is_safe_path "$user_file" "/var/app/data"; then
    process_file "$user_file"
else
    echo "Error: 無効なファイルパス" >&2
    exit 1
fi

権限管理

# rootで実行しているかチェック
if [[ $EUID -eq 0 ]]; then
    echo "Error: このスクリプトをrootで実行しないでください" >&2
    exit 1
fi

# 必要に応じて権限をドロップ
drop_privileges() {
    local user="$1"

    if [[ $EUID -eq 0 ]]; then
        exec sudo -u "$user" "$0" "$@"
    fi
}

# 特定のコマンドを昇格権限で実行
run_as_root() {
    if [[ $EUID -ne 0 ]]; then
        sudo "$@"
    else
        "$@"
    fi
}

一時ファイル処理

# セキュアな一時ファイルを作成
readonly TEMP_DIR=$(mktemp -d)
readonly TEMP_FILE=$(mktemp)

# 終了時にクリーンアップ
cleanup() {
    rm -rf "$TEMP_DIR"
    rm -f "$TEMP_FILE"
}
trap cleanup EXIT

# セキュアな一時ファイル (所有者のみが読み取り可能)
secure_temp=$(mktemp)
chmod 600 "$secure_temp"

パフォーマンス最適化

不要なサブシェルを避ける

# ✗ 遅い - 各イテレーションでサブシェルを作成
while IFS= read -r line; do
    count=$(echo "$count + 1" | bc)
done < file.txt

# ✓ 速い - bashで算術
count=0
while IFS= read -r line; do
    ((count++))
done < file.txt

bashビルトインを使用

# ✗ 遅い - 外部コマンド
dirname=$(dirname "$path")
basename=$(basename "$path")

# ✓ 速い - パラメータ展開
dirname="${path%/*}"
basename="${path##*/}"

# ✗ 遅い - grepで単純なチェック
if echo "$string" | grep -q "pattern"; then

# ✓ 速い - bash正規表現
if [[ "$string" =~ pattern ]]; then

# ✗ 遅い - 単純な抽出用のawk
field=$(echo "$line" | awk '{print $3}')

# ✓ 速い - 配列に読み込み
read -ra fields <<< "$line"
field="${fields[2]}"

プロセス置換 vs パイプ

# 複数のコマンドの出力を読み込む必要がある場合
# ✓ 良い - プロセス置換
while IFS= read -r line1 <&3 && IFS= read -r line2 <&4; do
    echo "$line1 - $line2"
done 3< <(command1) 4< <(command2)

# 並列処理
command1 &
command2 &
wait  # すべてのバックグラウンドジョブを待機

配列操作

# ✓ 速い - ネイティブ配列操作
files=(*.txt)
echo "見つかったファイル数: ${#files[@]}"

# ✗ 遅い - ls出力の解析
count=$(ls -1 *.txt | wc -l)

# ✓ 速い - 配列フィルタリング
filtered=()
for item in "${array[@]}"; do
    [[ "$item" =~ ^[0-9]+$ ]] && filtered+=("$item")
done

# ✓ 速い - 配列結合
IFS=,
joined="${array[*]}"
IFS=$'\n\t'

テスト

BATSでのユニットテスト

# BATSをインストール
# git clone https://github.com/bats-core/bats-core.git
# cd bats-core && ./install.sh /usr/local

# test/script.bats
#!/usr/bin/env bats

# テストするスクリプトをロード
load '../script.sh'

@test "関数が正しい値を返す" {
    result=$(my_function "input")
    [ "$result" = "expected" ]
}

@test "関数が空の入力を処理" {
    run my_function ""
    [ "$status" -eq 1 ]
    [ "${lines[0]}" = "Error: 入力は空にできません" ]
}

@test "関数が入力形式を検証" {
    run my_function "invalid@input"
    [ "$status" -eq 1 ]
}

# テストを実行
# bats test/script.bats

統合テスト

# integration_test.sh
#!/usr/bin/env bash
set -euo pipefail

# セットアップ
setup() {
    export TEST_DIR=$(mktemp -d)
    export TEST_FILE="$TEST_DIR/test.txt"
}

# ティアダウン
teardown() {
    rm -rf "$TEST_DIR"
}

# テストケース
test_file_creation() {
    ./script.sh create "$TEST_FILE"

    if [[ ! -f "$TEST_FILE" ]]; then
        echo "失敗: ファイルが作成されませんでした"
        return 1
    fi

    echo "成功: ファイル作成が動作"
    return 0
}

# テストを実行
main() {
    setup
    trap teardown EXIT

    test_file_creation || exit 1

    echo "すべてのテストに成功"
}

main

CI/CD統合

# .github/workflows/test.yml
name: Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: ShellCheckをインストール
        run: sudo apt-get install -y shellcheck

      - name: ShellCheckを実行
        run: find . -name "*.sh" -exec shellcheck {} +

      - name: BATSをインストール
        run: |
          git clone https://github.com/bats-core/bats-core.git
          cd bats-core
          sudo ./install.sh /usr/local

      - name: テストを実行
        run: bats test/

デバッグ技法

デバッグモード

# 方法1: set -x (コマンドを表示)
set -x
command1
command2
set +x  # 無効化

# 方法2: より良い出力用にPS4
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -x

# 方法3: 条件付きデバッグ
DEBUG=${DEBUG:-false}
debug() {
    if [[ "$DEBUG" == "true" ]]; then
        echo "[DEBUG] $*" >&2
    fi
}

# 使用方法: DEBUG=true ./script.sh

トレースとプロファイリング

# 関数呼び出しをトレース
trace() {
    echo "[TRACE] 関数: ${FUNCNAME[1]}, 引数: $*" >&2
}

my_function() {
    trace "$@"
    # 関数ロジック
}

# 実行時間プロファイリング
profile() {
    local start=$(date +%s%N)
    "$@"
    local end=$(date +%s%N)
    local duration=$(( (end - start) / 1000000 ))
    echo "[PROFILE] コマンド '$*' は ${duration}ms かかりました" >&2
}

# 使用方法
profile slow_command arg1 arg2

一般的な問題と解決策

# 問題: bashでは動作するが、shでは動作しない
# 解決策: bashismをチェック
checkbashisms script.sh

# 問題: ローカルでは動作するがサーバーでは動作しない
# 解決策: PATHと環境をチェック
env
echo "$PATH"

# 問題: ファイル名のスペースがスクリプトを破裂させる
# 解決策: 常に変数をクォート
for file in *.txt; do
    process "$file"  # この例では: process $file ではなく
done

# 問題: スクリプトがcronで異なる動作
# 解決策: PATHを明示的に設定
PATH=/usr/local/bin:/usr/bin:/bin
export PATH

高度なパターン

設定ファイル解析

# シンプルなkey=valueの設定
load_config() {
    local config_file="$1"

    if [[ ! -f "$config_file" ]]; then
        echo "Error: 設定ファイルが見つかりません: $config_file" >&2
        return 1
    fi

    # 設定をソース (信頼できない場合は危険)
    # shellcheck source=/dev/null
    source "$config_file"
}

# 安全な設定解析 (コード実行なし)
read_config() {
    local config_file="$1"

    while IFS='=' read -r key value; do
        # コメントと空行をスキップ
        [[ "$key" =~ ^[[:space:]]*# ]] && continue
        [[ -z "$key" ]] && continue

        # 空白をトリミング
        key=$(echo "$key" | tr -d ' ')
        value=$(echo "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

        # 変数をエクスポート
        declare -g "$key=$value"
    done < "$config_file"
}

並列処理

# シンプルなバックグラウンドジョブ
process_files_parallel() {
    local max_jobs=4
    local job_count=0

    for file in *.txt; do
        # バックグラウンドジョブを開始
        process_file "$file" &

        # 同時実行ジョブを制限
        ((job_count++))
        if [[ $job_count -ge $max_jobs ]]; then
            wait -n  # いずれかのジョブが完了するまで待機
            ((job_count--))
        fi
    done

    # 残りのジョブを待機
    wait
}

# GNU Parallel (利用可能な場合)
parallel_with_gnu() {
    parallel -j 4 process_file ::: *.txt
}

シグナルハンドリング

# グレースフルシャットダウン
shutdown_requested=false

handle_sigterm() {
    echo "SIGTERMを受信し、グレースフルシャットダウン中..." >&2
    shutdown_requested=true
}

trap handle_sigterm SIGTERM SIGINT

main_loop() {
    while [[ "$shutdown_requested" == "false" ]]; do
        # 作業を実行
        sleep 1
    done

    echo "シャットダウン完了" >&2
}

main_loop

指数バックオフでの再試行

retry_with_backoff() {
    local max_attempts=5
    local timeout=1
    local attempt=1
    local exitCode=0

    while [[ $attempt -le $max_attempts ]]; do
        if "$@"; then
            return 0
        else
            exitCode=$?
        fi

        echo "試行 $attempt が失敗しました! $timeout秒後に再試行中..." >&2
        sleep "$timeout"
        attempt=$((attempt + 1))
        timeout=$((timeout * 2))
    done

    echo "$max_attempts回の試行後、コマンドが失敗しました!" >&2
    return "$exitCode"
}

# 使用方法
retry_with_backoff curl -f https://api.example.com/health

追加情報のためのリソース

公式ドキュメント

  1. Bash Reference Manual

  2. POSIX Shell Command Language

スタイルガイド

  1. Google Shell Style Guide

  2. Defensive Bash Programming

ツール

  1. ShellCheck

  2. BATS (Bash Automated Testing System)

  3. shfmt

学習リソース

  1. Bash Academy

  2. Bash Guide for Beginners

  3. Advanced Bash-Scripting Guide

  4. Bash Pitfalls

  5. explainshell.com

プラットフォーム固有リソース

  1. GNU Coreutils Manual

  2. FreeBSD Manual Pages

  3. Git for Windows

  4. WSL Documentation

コミュニティリソース

  1. Stack Overflow - Bashタグ

  2. Unix & Linux Stack Exchange

  3. Reddit - r/bash

クイックリファレンス

  1. Bash Cheat Sheet

  2. ShellCheck Wiki


リファレンスファイル

特定のトピックについてのより詳細なカバレッジは、リファレンスファイルを参照してください:

  • references/platform_specifics.md - 詳細なプラットフォーム違いと回避方法
  • references/best_practices.md - 包括的な業界標準とガイドライン
  • references/patterns_antipatterns.md - 一般的なパターンと解決策を伴う落とし穴

このスキルを使用する場合

常にアクティベートする:

  • 新しいbashスクリプトを作成
  • 既存スクリプトをレビュー/リファクタリング
  • シェルスクリプトの問題をデバッグ
  • クロスプラットフォームシェルスクリプティング
  • DevOps自動化タスク
  • CI/CDパイプラインスクリプト
  • システム管理者自動化

重要な指標:

  • ユーザーがbash、shell、またはscriptに言及
  • タスクが自動化に関係
  • プラットフォーム互換性が懸念事項
  • セキュリティまたは堅牢性が重要
  • パフォーマンス最適化が必要

成功基準

このスキルを使用するbashスクリプトは:

  1. ✓ ShellCheckに合格し警告がない
  2. ✓ 適切なエラーハンドリング (set -euo pipefail) を含む
  3. ✓ すべての変数展開をクォート
  4. ✓ 使用方法/ヘルプテキストを含む
  5. ✓ 再利用可能なロジック用に関数を使用
  6. ✓ 適切なコメントを含む
  7. ✓ エッジケースを処理 (空入力、ファイルなし、など)
  8. ✓ ターゲットプラットフォーム間で動作
  9. ✓ 一貫したスタイルに従う (Google Shell Style Guide)
  10. ✓ クリーンアップを含む (trap EXIT)

品質チェックリスト:

# デプロイ前に実行
shellcheck script.sh              # エラーまたは警告なし
bash -n script.sh                 # 構文チェック
bats test/script.bats             # ユニットテスト成功
./script.sh --help                # 使用方法テキスト表示
DEBUG=true ./script.sh            # デバッグモード動作

トラブルシューティング

スクリプトが別のプラットフォームで失敗

  1. bashismをチェック: checkbashisms script.sh
  2. コマンドが存在することを確認: command -v tool_name
  3. コマンドフラグをテスト: sed --version (GNU) vs sed (BSD)

ShellCheck警告

  1. 説明を読む: shellcheck -W SC2086
  2. 問題を修正 (無効化するだけではない)
  3. 正当な理由を示して無効化のみ: # shellcheck disable=SC2086 理由: 意図的な単語分割

スクリプトは対話的に動作するが、cronで失敗

  1. PATHを明示的に設定
  2. 絶対パスを使用
  3. デバッグ出力をリダイレクト: ./script.sh >> /tmp/cron.log 2>&1

パフォーマンス問題

  1. time commandでプロファイル
  2. トレースを有効化: set -x
  3. 不要なサブシェルと外部コマンドを避ける
  4. 可能な場所ではbashビルトインを使用

このスキルは包括的なbashスクリプティング知識を提供します。リファレンスファイルと組み合わせると、あらゆるbashスクリプティングタスク向けの業界標準的なプラクティスとプラットフォーム固有のガイダンスにアクセスできます。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
josiahsiegel
リポジトリ
josiahsiegel/claude-plugin-marketplace
ライセンス
MIT
最終更新
不明

Source: https://github.com/josiahsiegel/claude-plugin-marketplace / ライセンス: MIT

関連スキル

汎用DevOps・インフラ⭐ リポ 502

superpowers-streamer-cli

SuperPowers デスクトップストリーマーの npm パッケージをインストール、ログイン、実行、トラブルシューティングできます。ユーザーが npm から `superpowers-ai` をセットアップしたい場合、メールまたは電話でサインインもしくはアカウント作成を行いたい場合、ストリーマーを起動したい場合、表示されたコントロールリンクを開きたい場合、後で停止したい場合、またはソースコードへのアクセスなしに npm やランタイムの一般的な問題から復旧したい場合に使用します。

by rohanarun
汎用DevOps・インフラ⭐ リポ 493

catc-client-ops

Catalyst Centerのクライアント操作・監視機能 - 有線・無線クライアントのリスト表示・フィルタリング、MACアドレスによる詳細なクライアント検索、クライアント数分析、時間軸での分析、SSIDおよび周波数帯によるフィルタリング、無線トラブルシューティング機能を提供します。MACアドレスやIPアドレスでのクライアント検索、サイト別やSSID別のクライアント数集計、無線周波数帯の分布分析、Wi-Fi信号の問題調査が必要な場合に活用できます。

by automateyournetwork
汎用DevOps・インフラ⭐ リポ 39,967

ci-cd-and-automation

CI/CDパイプラインの設定を自動化します。ビルドおよびデプロイメントパイプラインの構築または変更時に使用できます。品質ゲートの自動化、CI内のテストランナー設定、またはデプロイメント戦略の確立が必要な場合に活用します。

by addyosmani
汎用DevOps・インフラ⭐ リポ 39,967

shipping-and-launch

本番環境へのリリース準備を行います。本番環境へのデプロイ準備が必要な場合、リリース前チェックリストが必要な場合、監視機能の設定を行う場合、段階的なロールアウトを計画する場合、またはロールバック戦略が必要な場合に使用します。

by addyosmani
OpenAIDevOps・インフラ⭐ リポ 38,974

linear-release-setup

Linear Releaseに向けたCI/CD設定を生成します。リリース追跡の設定、LinearのCIパイプライン構築、またはLinearリリースとのデプロイメント連携を実施する際に利用できます。GitHub Actions、GitLab CI、CircleCIなど複数のプラットフォームに対応しています。

by novuhq
Anthropic ClaudeDevOps・インフラ⭐ リポ 2,159

tracking-application-response-times

API エンドポイント、データベースクエリ、サービスコール全体にわたるアプリケーションのレスポンスタイムを追跡・最適化できます。パフォーマンス監視やボトルネック特定の際に活用してください。「レスポンスタイムを追跡する」「API パフォーマンスを監視する」「遅延を分析する」といった表現で呼び出せます。

by jeremylongshore
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: josiahsiegel · josiahsiegel/claude-plugin-marketplace · ライセンス: MIT