script-development
スクリプト開発ガイド。Shell、Python、Node.jsスクリプト、自動化、バッチ処理、環境変数管理など、効率的なスクリプト開発のベストプラクティス。
When & Why to Use This Skill
This Claude skill serves as a comprehensive guide for efficient script development across Shell, Python, and Node.js. It provides best practices for automation, batch processing, environment variable management, and robust error handling, enabling developers to create maintainable and high-performance scripts for various technical workflows.
Use Cases
- Automating Repetitive Tasks: Streamline system maintenance, file manipulations, and routine administrative duties using optimized Shell or Python scripts.
- DevOps and Deployment: Create reliable deployment pipelines and CI/CD scripts with strict error checking and environment-specific configurations.
- Data Processing and Migration: Develop scripts to handle CSV/JSON data, perform database migrations, and automate API interactions using Python or Node.js.
- CLI Tool Development: Build professional command-line interfaces with advanced argument parsing and logging capabilities for internal tooling.
| name | script-development |
|---|---|
| description | スクリプト開発ガイド。Shell、Python、Node.jsスクリプト、自動化、バッチ処理、環境変数管理など、効率的なスクリプト開発のベストプラクティス。 |
Script Development Skill
📋 目次
概要
このSkillは、スクリプト開発をカバーします:
- Shell スクリプト - Bash/Zsh
- Python スクリプト - 自動化、データ処理
- Node.js スクリプト - TypeScript/JavaScript
- 環境変数管理 - .env、dotenv
- エラーハンドリング - 適切なエラー処理
- ログ出力 - 実行ログ記録
📚 公式ドキュメント・参考リソース
このガイドで学べること: Shell/Python/Node.jsスクリプトの基本文法、自動化パターン、環境変数管理、エラーハンドリング 公式で確認すべきこと: 最新の言語機能、セキュリティベストプラクティス、パッケージのアップデート
主要な公式ドキュメント
Bash Reference Manual - Bash公式リファレンス
Python Documentation - Python公式ドキュメント
Node.js Documentation - Node.js公式ドキュメント
Commander.js - Node.js CLIフレームワーク
関連リソース
- ShellCheck - Shellスクリプトの静的解析ツール
- Python Click - Pythonコマンドラインインターフェース
- Google Shell Style Guide - Shellスクリプトスタイルガイド
いつ使うか
🎯 必須のタイミング
- 繰り返し作業の自動化時
- デプロイスクリプト作成時
- データ移行スクリプト作成時
- 定期実行バッチ作成時
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 ファイルに出力
まとめ
スクリプト開発のベストプラクティス
- エラーハンドリング - set -e(Shell)、try-catch(Python/Node.js)
- 環境変数 - .envファイルで管理
- 引数パース - argparse(Python)、commander(Node.js)
- ログ出力 - 実行状況を記録
Last updated: 2025-12-24