Claude Code Plugins

Community-maintained marketplace

Feedback

script-development

@Gaku52/claude-code-skills
1
0

スクリプト開発ガイド。Shell、Python、Node.jsスクリプト、自動化、バッチ処理、環境変数管理など、効率的なスクリプト開発のベストプラクティス。

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name script-development
description スクリプト開発ガイド。Shell、Python、Node.jsスクリプト、自動化、バッチ処理、環境変数管理など、効率的なスクリプト開発のベストプラクティス。

Script Development Skill

📋 目次

  1. 概要
  2. いつ使うか
  3. Shell スクリプト
  4. Python スクリプト
  5. Node.js スクリプト
  6. 環境変数管理
  7. 実践例
  8. Agent連携

概要

このSkillは、スクリプト開発をカバーします:

  • Shell スクリプト - Bash/Zsh
  • Python スクリプト - 自動化、データ処理
  • Node.js スクリプト - TypeScript/JavaScript
  • 環境変数管理 - .env、dotenv
  • エラーハンドリング - 適切なエラー処理
  • ログ出力 - 実行ログ記録

いつ使うか

🎯 必須のタイミング

  • 繰り返し作業の自動化時
  • デプロイスクリプト作成時
  • データ移行スクリプト作成時
  • 定期実行バッチ作成時

Shell スクリプト

基本構文

#!/bin/bash

# 変数
NAME="John"
echo "Hello, $NAME"

# コマンドライン引数
echo "First arg: $1"
echo "All args: $@"
echo "Number of args: $#"

# 条件分岐
if [ "$1" = "production" ]; then
  echo "Production mode"
elif [ "$1" = "development" ]; then
  echo "Development mode"
else
  echo "Unknown mode"
fi

# ループ
for file in *.txt; do
  echo "Processing $file"
done

# 関数
function greet() {
  local name=$1
  echo "Hello, $name"
}

greet "Alice"

# エラーハンドリング
set -e  # エラー時に終了
set -u  # 未定義変数使用時にエラー
set -o pipefail  # パイプライン内のエラーを検知

# コマンド実行結果の取得
CURRENT_BRANCH=$(git branch --show-current)
echo "Current branch: $CURRENT_BRANCH"

実用例:デプロイスクリプト

#!/bin/bash

# deploy.sh
set -euo pipefail

ENV=${1:-development}

echo "🚀 Deploying to $ENV..."

# ビルド
echo "📦 Building..."
npm run build

# テスト
echo "🧪 Running tests..."
npm test

# デプロイ
if [ "$ENV" = "production" ]; then
  echo "🌍 Deploying to production..."
  ssh user@server 'cd /var/www && git pull && pm2 restart app'
else
  echo "🔧 Deploying to development..."
  ssh user@dev-server 'cd /var/www && git pull && pm2 restart app'
fi

echo "✅ Deploy complete!"

Python スクリプト

基本構文

#!/usr/bin/env python3

import sys
import os
from pathlib import Path

def main():
    # コマンドライン引数
    if len(sys.argv) < 2:
        print("Usage: script.py <file>")
        sys.exit(1)

    file_path = sys.argv[1]

    # ファイル存在確認
    if not Path(file_path).exists():
        print(f"Error: {file_path} does not exist")
        sys.exit(1)

    # ファイル処理
    with open(file_path, 'r') as f:
        content = f.read()
        print(f"File size: {len(content)} bytes")

if __name__ == "__main__":
    main()

argparse(推奨)

#!/usr/bin/env python3

import argparse
from pathlib import Path

def process_file(file_path: Path, output: Path | None, verbose: bool):
    if verbose:
        print(f"Processing {file_path}...")

    with open(file_path, 'r') as f:
        content = f.read()

    # 処理
    result = content.upper()

    if output:
        with open(output, 'w') as f:
            f.write(result)
        if verbose:
            print(f"Saved to {output}")
    else:
        print(result)

def main():
    parser = argparse.ArgumentParser(description='Process a file')
    parser.add_argument('input', type=Path, help='Input file path')
    parser.add_argument('-o', '--output', type=Path, help='Output file path')
    parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')

    args = parser.parse_args()

    if not args.input.exists():
        parser.error(f"{args.input} does not exist")

    process_file(args.input, args.output, args.verbose)

if __name__ == "__main__":
    main()

# 使用例:
# python script.py input.txt
# python script.py input.txt -o output.txt -v

データ処理スクリプト

#!/usr/bin/env python3

import pandas as pd
import argparse
from pathlib import Path

def process_csv(input_path: Path, output_path: Path):
    # CSV読み込み
    df = pd.read_csv(input_path)

    # データ処理
    df['total'] = df['price'] * df['quantity']
    df_filtered = df[df['total'] > 1000]

    # 出力
    df_filtered.to_csv(output_path, index=False)
    print(f"✅ Processed {len(df)} rows → {len(df_filtered)} rows")

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('input', type=Path)
    parser.add_argument('output', type=Path)
    args = parser.parse_args()

    process_csv(args.input, args.output)

if __name__ == "__main__":
    main()

Node.js スクリプト

基本構文(TypeScript)

#!/usr/bin/env ts-node

import { readFileSync, writeFileSync } from 'fs'
import { program } from 'commander'

program
  .name('process-file')
  .description('Process a file')
  .argument('<input>', 'Input file path')
  .option('-o, --output <path>', 'Output file path')
  .option('-v, --verbose', 'Verbose output')
  .action((input, options) => {
    if (options.verbose) {
      console.log(`Processing ${input}...`)
    }

    const content = readFileSync(input, 'utf-8')
    const result = content.toUpperCase()

    if (options.output) {
      writeFileSync(options.output, result)
      if (options.verbose) {
        console.log(`Saved to ${options.output}`)
      }
    } else {
      console.log(result)
    }
  })

program.parse()

// package.json
{
  "scripts": {
    "process": "ts-node src/process.ts"
  },
  "bin": {
    "process-file": "./dist/process.js"
  }
}

ファイル操作

import fs from 'fs/promises'
import path from 'path'

async function processFiles(dirPath: string) {
  try {
    // ディレクトリ内のファイル一覧取得
    const files = await fs.readdir(dirPath)

    for (const file of files) {
      const filePath = path.join(dirPath, file)
      const stat = await fs.stat(filePath)

      if (stat.isFile() && file.endsWith('.txt')) {
        // ファイル処理
        const content = await fs.readFile(filePath, 'utf-8')
        const processed = content.toUpperCase()

        await fs.writeFile(filePath, processed)
        console.log(`Processed: ${file}`)
      }
    }
  } catch (error) {
    console.error('Error:', error)
    process.exit(1)
  }
}

processFiles('./data')

API呼び出し

import axios from 'axios'

async function fetchUsers() {
  try {
    const response = await axios.get('https://api.example.com/users', {
      headers: {
        'Authorization': `Bearer ${process.env.API_TOKEN}`
      }
    })

    console.log(`Fetched ${response.data.length} users`)

    // CSVに出力
    const csv = response.data
      .map((user: any) => `${user.id},${user.name},${user.email}`)
      .join('\n')

    await fs.writeFile('users.csv', `id,name,email\n${csv}`)
    console.log('✅ Saved to users.csv')
  } catch (error) {
    console.error('Error:', error)
    process.exit(1)
  }
}

fetchUsers()

環境変数管理

.env ファイル

# .env
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=your_api_key_here
NODE_ENV=development

Node.js(dotenv)

import 'dotenv/config'

console.log(process.env.DATABASE_URL)
console.log(process.env.API_KEY)

// 必須チェック
const requiredEnvVars = ['DATABASE_URL', 'API_KEY']

for (const envVar of requiredEnvVars) {
  if (!process.env[envVar]) {
    console.error(`Error: ${envVar} is not set`)
    process.exit(1)
  }
}

Python(python-dotenv)

from dotenv import load_dotenv
import os

load_dotenv()

DATABASE_URL = os.getenv('DATABASE_URL')
API_KEY = os.getenv('API_KEY')

# 必須チェック
required_env_vars = ['DATABASE_URL', 'API_KEY']

for env_var in required_env_vars:
    if not os.getenv(env_var):
        print(f"Error: {env_var} is not set")
        exit(1)

Shell

#!/bin/bash

# .envファイルを読み込み
if [ -f .env ]; then
  export $(cat .env | grep -v '^#' | xargs)
fi

echo "DATABASE_URL: $DATABASE_URL"

実践例

Example 1: データ移行スクリプト(Python)

#!/usr/bin/env python3

import psycopg2
from dotenv import load_dotenv
import os
import sys

load_dotenv()

def migrate_data():
    # 接続
    conn = psycopg2.connect(os.getenv('DATABASE_URL'))
    cur = conn.cursor()

    try:
        # データ移行
        cur.execute("""
            INSERT INTO new_users (id, name, email)
            SELECT id, name, email FROM old_users
            WHERE migrated = false
        """)

        # フラグ更新
        cur.execute("UPDATE old_users SET migrated = true")

        conn.commit()
        print(f"✅ Migrated {cur.rowcount} rows")

    except Exception as e:
        conn.rollback()
        print(f"❌ Error: {e}")
        sys.exit(1)

    finally:
        cur.close()
        conn.close()

if __name__ == "__main__":
    migrate_data()

Example 2: 定期バックアップスクリプト(Shell)

#!/bin/bash

# backup.sh
set -euo pipefail

BACKUP_DIR="/var/backups/db"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_$DATE.sql.gz"

# ディレクトリ作成
mkdir -p "$BACKUP_DIR"

# バックアップ実行
echo "📦 Creating backup..."
pg_dump -U postgres mydb | gzip > "$BACKUP_FILE"

echo "✅ Backup saved: $BACKUP_FILE"

# 古いバックアップ削除(7日以上前)
find "$BACKUP_DIR" -name "backup_*.sql.gz" -mtime +7 -delete
echo "🗑️  Old backups deleted"

# crontabで毎日実行
# 0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1

Agent連携

📖 Agentへの指示例

Shell スクリプト作成

以下を行うShell スクリプトを作成してください:
1. GitHubから最新コードをpull
2. npmビルド実行
3. PM2でアプリ再起動
4. エラー時は通知

Python データ処理スクリプト作成

CSV ファイルを読み込み、以下の処理を行うPython スクリプトを作成してください:
- priceとquantityからtotalを計算
- total > 1000の行のみフィルタリング
- 結果を新しいCSV ファイルに出力

まとめ

スクリプト開発のベストプラクティス

  1. エラーハンドリング - set -e(Shell)、try-catch(Python/Node.js)
  2. 環境変数 - .envファイルで管理
  3. 引数パース - argparse(Python)、commander(Node.js)
  4. ログ出力 - 実行状況を記録

Last updated: 2025-12-24