AIコーディング 2026.04.19

Claude CodeでPython・シェルスクリプトを実行する完全ガイド【実例コード付き】

タグ:Claude Code / Python / シェルスクリプト / 自動化 / 開発ツール

Claude CodeがPython・シェルを実行する仕組み

Claude CodeはBashツールを通じてローカルのターミナルでコマンドを実行します。クラウドサンドボックスではなくあなたのマシン上で直接実行するため:

  • インストール済みのPythonパッケージが使える
  • ファイルシステムへの読み書きができる
  • 環境変数・認証情報がそのまま使える
  • ネットワークアクセスが可能

これはChatGPT Code Interpreterとの大きな違いです。ChatGPTは隔離されたサンドボックスで動きますが、Claude Codeはローカル環境でフルに動作します。

基本的な使い方

インタラクティブモードで実行させる

# Claude Codeを起動
claude

# 会話の中でスクリプト実行を依頼する
> data.csvを読み込んで、売上の月次集計をPythonで計算して
> 結果をsummary.csvに出力して

ワンショットで実行

# -p オプションで1回実行
claude -p "logs/access.log を分析して、ステータスコード別のリクエスト数を集計して表示して"

# ファイルを指定して実行
claude -p "src/process_data.py を実行して、エラーが出たら修正して再実行して"

実例1:CSVデータ処理

データ処理の典型的なワークフローです。

> sales_data.csv のデータを分析して:
> 1. 月別の売上合計を計算
> 2. 売上トップ5商品をリストアップ  
> 3. 前月比の増減率を計算
> 結果をExcelで見やすくまとめて output.xlsx に保存して

Claude Codeが生成・実行するPythonスクリプト例:

import pandas as pd
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill
from openpyxl.utils.dataframe import dataframe_to_rows

# データ読み込み
df = pd.read_csv("sales_data.csv", encoding="utf-8")
df["date"] = pd.to_datetime(df["date"])
df["month"] = df["date"].dt.to_period("M")

# 月別売上集計
monthly = df.groupby("month")["amount"].sum().reset_index()
monthly.columns = ["月", "売上合計"]
monthly["前月比"] = monthly["売上合計"].pct_change() * 100

# トップ5商品
top5 = (
    df.groupby("product")["amount"]
    .sum()
    .sort_values(ascending=False)
    .head(5)
    .reset_index()
)
top5.columns = ["商品名", "売上合計"]

# Excelに書き出し
wb = Workbook()
ws1 = wb.active
ws1.title = "月別集計"

# ヘッダーを太字に
for r in dataframe_to_rows(monthly, index=False, header=True):
    ws1.append(r)
for cell in ws1[1]:
    cell.font = Font(bold=True)

ws2 = wb.create_sheet("トップ5商品")
for r in dataframe_to_rows(top5, index=False, header=True):
    ws2.append(r)
for cell in ws2[1]:
    cell.font = Font(bold=True)

wb.save("output.xlsx")
print("output.xlsx に保存しました")

Claude Codeはこのスクリプトを生成した後、実際に実行して結果を確認します。

実例2:ログファイル集計

> logs/ ディレクトリ以下の全アクセスログを集計して:
> - ステータスコード別のリクエスト数
> - 上位10のURLパス  
> - エラー率(4xx/5xxの割合)
> 日本語でレポートして

Claude Codeが実行するシェルコマンド+Python:

# まずログファイルの確認
ls -la logs/
wc -l logs/*.log
import re
from pathlib import Path
from collections import Counter

log_pattern = re.compile(
    r'(\S+) \S+ \S+ \[.+?\] "(\S+) (\S+) \S+" (\d{3}) (\d+|-)'
)

status_counts = Counter()
path_counts = Counter()
total = 0
errors = 0

for log_file in Path("logs").glob("*.log"):
    with open(log_file) as f:
        for line in f:
            m = log_pattern.match(line)
            if not m:
                continue
            _, method, path, status, _ = m.groups()
            status_int = int(status)
            
            total += 1
            status_counts[status_int] += 1
            path_counts[path] += 1
            if status_int >= 400:
                errors += 1

print(f"総リクエスト数: {total:,}")
print(f"\nステータスコード別:")
for status, count in sorted(status_counts.items()):
    print(f"  {status}: {count:,} ({count/total*100:.1f}%)")

print(f"\n上位10 URL:")
for path, count in path_counts.most_common(10):
    print(f"  {count:>8,}  {path}")

print(f"\nエラー率: {errors/total*100:.2f}% ({errors:,}/{total:,})")

実例3:シェルスクリプトでgitリポジトリを整理

> 過去3ヶ月以上更新されていないブランチを一覧表示して
> リモートブランチも含めて確認したい
# Claude Codeが実行するシェルコマンド

# ローカルブランチ(3ヶ月以上更新なし)
git branch -v | while read branch hash message; do
  last_commit=$(git log -1 --format="%ci" "$branch" 2>/dev/null)
  if [ -n "$last_commit" ]; then
    days_ago=$(( ($(date +%s) - $(date -d "$last_commit" +%s 2>/dev/null || date -j -f "%Y-%m-%d %H:%M:%S %z" "$last_commit" +%s)) / 86400 ))
    if [ "$days_ago" -gt 90 ]; then
      echo "$days_ago 日前  $branch  最終更新: $last_commit"
    fi
  fi
done | sort -rn
# リモートブランチも確認
git fetch --prune
git branch -r --sort=-committerdate \
  --format="%(committerdate:relative)  %(refname:short)" | \
  grep -v HEAD | head -20

実例4:定期実行スクリプトの作成

「毎朝9時にAPIから在庫データを取得してSlackに通知したい」という依頼例:

> 毎朝9時に inventory API から在庫データを取得して
> 在庫が10個以下の商品をSlackに通知するPythonスクリプトを作って
> crontabへの登録方法も教えて

Claude Codeが生成するスクリプト:

#!/usr/bin/env python3
# check_inventory.py

import os
import json
import urllib.request
from datetime import datetime

INVENTORY_API = os.environ["INVENTORY_API_URL"]
SLACK_WEBHOOK = os.environ["SLACK_WEBHOOK_URL"]
LOW_STOCK_THRESHOLD = 10

def fetch_inventory() -> list[dict]:
    req = urllib.request.Request(
        INVENTORY_API,
        headers={"Authorization": f"Bearer {os.environ['INVENTORY_API_KEY']}"}
    )
    with urllib.request.urlopen(req) as res:
        return json.loads(res.read())["items"]

def post_to_slack(message: str) -> None:
    payload = json.dumps({"text": message}).encode()
    req = urllib.request.Request(
        SLACK_WEBHOOK,
        data=payload,
        headers={"Content-Type": "application/json"}
    )
    urllib.request.urlopen(req)

def main() -> None:
    items = fetch_inventory()
    low_stock = [item for item in items if item["quantity"] <= LOW_STOCK_THRESHOLD]

    if not low_stock:
        return

    lines = [f"⚠️ 在庫アラート ({datetime.now().strftime('%Y-%m-%d %H:%M')})"]
    for item in sorted(low_stock, key=lambda x: x["quantity"]):
        lines.append(f"• {item['name']}: 残り {item['quantity']} 個")

    post_to_slack("\n".join(lines))
    print(f"{len(low_stock)} 件の低在庫商品を通知しました")

if __name__ == "__main__":
    main()

crontab設定:

# crontabを編集
crontab -e

# 毎朝9時に実行(環境変数はスクリプト内でos.environから取得)
0 9 * * * /path/to/venv/bin/python /path/to/check_inventory.py >> /var/log/inventory.log 2>&1

よくあるエラーと対処法

ModuleNotFoundError

# エラー例
ModuleNotFoundError: No module named 'pandas'

# Claude Codeへの対処依頼
> pandas が入っていないみたい。インストールして再実行して

# Claude Codeが実行するコマンド
pip install pandas
python script.py

文字コードエラー(日本語ファイル)

# ❌ エラーが出るパターン
with open("data.csv") as f:
    data = f.read()

# ✅ Claude Codeが修正するパターン
with open("data.csv", encoding="utf-8-sig") as f:  # BOM付きCSV対応
    data = f.read()

権限エラー

# エラー例
PermissionError: [Errno 13] Permission denied: '/etc/hosts'

# Claude Codeへの依頼
> 権限エラーが出た。sudoが必要なら確認して実行して

GitHub Actions との連携

Claude Codeが作成したスクリプトをCI/CDに組み込む:

> check_inventory.py をGitHub Actionsで毎朝9時に実行するワークフローを作って
> 失敗時はメールで通知して
# .github/workflows/inventory-check.yml
name: 在庫チェック

on:
  schedule:
    - cron: '0 0 * * *'  # UTC 0時 = JST 9時
  workflow_dispatch:  # 手動実行用

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Python セットアップ
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      
      - name: 実行
        env:
          INVENTORY_API_URL: ${{ secrets.INVENTORY_API_URL }}
          INVENTORY_API_KEY: ${{ secrets.INVENTORY_API_KEY }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        run: python check_inventory.py

あわせて読みたい

参考ソース