mcpField
S
shell-scripting

shell-scripting

github.com/89jobrien開発462 回インストール9 週間前に更新
リポジトリ

shell-scripting について

開発者やシステム管理者向けのシェルスクリプトスキルです。Bash と zsh による自動化、エラー処理、CLI ツール開発のパターンを扱います。

主な機能

  1. 01Bash と zsh のパターン
  2. 02エラー処理とクリーンアップ
  3. 03変数、配列、制御フロー
  4. 04入出力とテキスト処理
  5. 05シェルスクリプトの実践指針

活用シーン

  1. 01自動化や定期実行スクリプトの作成
  2. 02コマンドラインツールの構築
  3. 03ビルド・デプロイスクリプトの作成
  4. 04ログや複数ファイルの処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/89jobrien/steve --skill shell-scripting

インストール後、Claude Code で/shell-scriptingを入力して読み込まれたか確認します。

詳細

シェルスクリプト

bash/zsh のパターン、自動化、エラー処理、CLI ツールの開発を網羅したシェルスクリプトのスキルです。

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

  • 自動化スクリプトを作成するとき
  • CLI ツールを作成するとき
  • システム管理タスクを行うとき
  • ビルドおよびデプロイのスクリプトを作成するとき
  • ログを処理および分析するとき
  • ファイル操作や一括処理を行うとき
  • cron ジョブやスケジュールされたタスクを設定するとき

スクリプトの構成

テンプレート
#!/usr/bin/env bash
# Script: name.sh
# Description: What this script does
# Usage: ./name.sh [options] <args>

set -euo pipefail  # Exit on error, undefined vars, pipe failures
IFS=$'\n\t'        # Safer word splitting

# Constants
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"

# Default values
VERBOSE=false
DRY_RUN=false

# Functions
usage() {
    cat <<EOF
Usage: $SCRIPT_NAME [options] <argument>

Options:
    -h, --help      Show this help message
    -v, --verbose   Enable verbose output
    -n, --dry-run   Show what would be done
EOF
}

log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2
}

error() {
    log "ERROR: $*"
    exit 1
}

# Main logic
main() {
    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -h|--help)
                usage
                exit 0
                ;;
            -v|--verbose)
                VERBOSE=true
                shift
                ;;
            -n|--dry-run)
                DRY_RUN=true
                shift
                ;;
            *)
                break
                ;;
        esac
    done

    # Your logic here
}

main "$@"

エラー処理

オプションの設定
set -e          # Exit on any error
set -u          # Error on undefined variables
set -o pipefail # Pipe failure is script failure
set -x          # Debug: print each command (use sparingly)
クリーンアップ用の trap
cleanup() {
    rm -f "$TEMP_FILE"
    log "Cleanup complete"
}
trap cleanup EXIT

# Also handle specific signals
trap 'error "Script interrupted"' INT TERM
エラーチェックのパターン
# Check command exists
command -v jq >/dev/null 2>&1 || error "jq is required but not installed"

# Check file exists
[[ -f "$FILE" ]] || error "File not found: $FILE"

# Check directory exists
[[ -d "$DIR" ]] || mkdir -p "$DIR"

# Check variable is set
[[ -n "${VAR:-}" ]] || error "VAR is not set"

# Check exit status explicitly
if ! some_command; then
    error "some_command failed"
fi

変数と置換

変数展開
# Default values
${VAR:-default}     # Use default if VAR is unset or empty
${VAR:=default}     # Set VAR to default if unset or empty
${VAR:+value}       # Use value if VAR is set
${VAR:?error msg}   # Error if VAR is unset or empty

# String manipulation
${VAR#pattern}      # Remove shortest prefix match
${VAR##pattern}     # Remove longest prefix match
${VAR%pattern}      # Remove shortest suffix match
${VAR%%pattern}     # Remove longest suffix match
${VAR/old/new}      # Replace first occurrence
${VAR//old/new}     # Replace all occurrences
${#VAR}             # Length of VAR
配列
# Declare array
declare -a ARRAY=("one" "two" "three")

# Access elements
echo "${ARRAY[0]}"     # First element
echo "${ARRAY[@]}"     # All elements
echo "${#ARRAY[@]}"    # Number of elements
echo "${!ARRAY[@]}"    # All indices

# Iterate
for item in "${ARRAY[@]}"; do
    echo "$item"
done

# Append
ARRAY+=("four")
連想配列
declare -A MAP
MAP["key1"]="value1"
MAP["key2"]="value2"

# Access
echo "${MAP[key1]}"

# Check key exists
[[ -v MAP[key1] ]] && echo "key1 exists"

# Iterate
for key in "${!MAP[@]}"; do
    echo "$key: ${MAP[$key]}"
done

制御フロー

条件分岐
# String comparison
[[ "$str" == "value" ]]
[[ "$str" != "value" ]]
[[ -z "$str" ]]  # Empty
[[ -n "$str" ]]  # Not empty

# Numeric comparison
[[ "$num" -eq 5 ]]  # Equal
[[ "$num" -ne 5 ]]  # Not equal
[[ "$num" -lt 5 ]]  # Less than
[[ "$num" -gt 5 ]]  # Greater than

# File tests
[[ -f "$file" ]]  # File exists
[[ -d "$dir" ]]   # Directory exists
[[ -r "$file" ]]  # Readable
[[ -w "$file" ]]  # Writable
[[ -x "$file" ]]  # Executable

# Logical operators
[[ "$a" && "$b" ]]  # AND
[[ "$a" || "$b" ]]  # OR
[[ ! "$a" ]]        # NOT
ループ
# For loop
for i in {1..10}; do
    echo "$i"
done

# While loop
while read -r line; do
    echo "$line"
done < "$file"

# Process substitution
while read -r line; do
    echo "$line"
done < <(command)

# C-style for
for ((i=0; i<10; i++)); do
    echo "$i"
done

入出力

入力の読み取り
# Read from user
read -r -p "Enter name: " name

# Read password (hidden)
read -r -s -p "Password: " password

# Read with timeout
read -r -t 5 -p "Quick! " answer

# Read file line by line
while IFS= read -r line; do
    echo "$line"
done < "$file"
出力とリダイレクト
# Redirect stdout
command > file      # Overwrite
command >> file     # Append

# Redirect stderr
command 2> file

# Redirect both
command &> file
command > file 2>&1

# Discard output
command > /dev/null 2>&1

# Tee (output and save)
command | tee file

テキスト処理

よく使うパターン
# Find and process files
find . -name "*.log" -exec grep "ERROR" {} +

# Process CSV
while IFS=, read -r col1 col2 col3; do
    echo "$col1: $col2"
done < file.csv

# JSON processing (with jq)
jq '.key' file.json
jq -r '.items[]' file.json

# AWK one-liners
awk '{print $1}' file           # First column
awk -F: '{print $1}' /etc/passwd  # Custom delimiter
awk 'NR > 1' file               # Skip header

# SED one-liners
sed 's/old/new/g' file          # Replace all
sed -i 's/old/new/g' file       # In-place edit
sed -n '10,20p' file            # Print lines 10-20

ベストプラクティス

推奨事項
  • すべての変数展開を引用符で囲みます:"$VAR"
  • テストには [ ] より [[ ]] を使います
  • バッククォートより $(command) を使います
  • 戻り値を確認します
  • 定数には readonly を使います
  • 関数内では local を使います
  • --help オプションを用意します
  • 意味のある終了コードを使います
避けるべきこと
  • ls の出力を解析すること
  • 信頼できない入力に eval を使うこと
  • パスに空白が含まれないと仮定すること
  • shellcheck の警告を無視すること
  • 1つの巨大なスクリプトを書くこと(モジュール化します)

参考ファイル

  • references/one_liners.md - 便利なワンライナーコマンド

他のスキルとの連携

  • developer-experience - ツールの自動化に使用します
  • debugging - スクリプトのデバッグに使用します
  • testing - スクリプトのテストパターンに使用します

コメント