Pythonスクリプト実行時にコマンドラインで環境変数を指定する方法

# Pythonスクリプト実行時にコマンドラインで環境変数を指定する方法

開発やテスト、本番環境でPythonスクリプトを実行する際、設定値を外部から動的に渡したいケースがあります。本記事では、コマンドライン実行時に環境変数を直接指定する方法と、その実用的なユースケースを詳しく解説します。

## 目次
1. [なぜコマンドラインで環境変数を指定するのか？](#なぜコマンドラインで環境変数を指定するのか)
2. [基本的な指定方法](#基本的な指定方法)
3. [実用的なユースケース](#実用的なユースケース)
4. [高度なテクニック](#高度なテクニック)
5. [注意点とベストプラクティス](#注意点とベストプラクティス)

## なぜコマンドラインで環境変数を指定するのか？

コマンドラインでの環境変数指定は以下のようなケースで非常に有効です：

### 主なメリット
- **一時的な設定変更**: ファイルを編集せずに実行時だけ設定を変更
- **CI/CDパイプライン**: ビルドやデプロイ時に動的に設定を注入
- **デバッグ**: 本番コードを変更せずにログレベルや設定を変更
- **テスト実行**: テスト用の設定で一時的に実行
- **並列実行**: 異なる設定で同じスクリプトを同時実行

## 基本的な指定方法

### Linux / macOS での指定方法

#### 1. 単一の環境変数

**実行コマンド:**
```bash
# 基本形
ENVIRONMENT_VARIABLE=value python script.py

# 実例：APIキーを指定
API_KEY=sk-1234567890 python api_client.py

# 実例：データベースホストを指定
DATABASE_URL=postgresql://localhost:5432/mydb python app.py
```

#### 2. 複数の環境変数

**実行コマンド:**
```bash
# スペース区切りで複数指定
API_KEY=sk-123 DATABASE_URL=postgres://localhost:5432/db python script.py

# 改行で読みやすく記述
API_KEY=sk-1234567890 \
DATABASE_URL=postgresql://localhost:5432/mydb \
LOG_LEVEL=DEBUG \
python data_processor.py
```

#### 3. envコマンドを使用

**実行コマンド:**
```bash
# envコマンドでより明示的に指定
env API_KEY=sk-123 DATABASE_URL=postgres://localhost/db python script.py

# 既存の環境変数をクリアして実行
env -i API_KEY=sk-123 python script.py

# 特定の環境変数のみ削除
env -u HOME API_KEY=sk-123 python script.py
```

## 実用的なユースケース

### 1. API統合テスト

**実行コマンド:**
```bash
# 本番API環境でテスト
API_KEY=prod_key API_BASE_URL=https://api.prod.com python test_api.py

# ステージング環境でテスト
API_KEY=stage_key API_BASE_URL=https://api.stage.com API_TIMEOUT=60 python test_api.py

# ローカル環境でテスト
API_KEY=dev_key API_BASE_URL=http://localhost:8000 python test_api.py
```

### 2. データベース接続設定

**実行コマンド:**
```bash
# 本番データベースへの接続
DATABASE_URL=postgresql://user:pass@prod.db.com:5432/prod_db python migrate.py

# テストデータベースでのマイグレーション確認
DATABASE_URL=postgresql://test:test@localhost:5432/test_db DRY_RUN=true python migrate.py
```

### 3. ログ設定の動的変更

**実行コマンド:**
```bash
# 通常実行（デフォルトのログレベル）
python logger_app.py

# デバッグモード
LOG_LEVEL=DEBUG python logger_app.py

# 本番環境でのエラーログのみ
LOG_LEVEL=ERROR LOG_FORMAT=json python logger_app.py
```

### 4. 外部サービス連携

**実行コマンド:**
```bash
# AWS S3への接続
AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=secret... S3_BUCKET=my-bucket python upload.py

# SendGridでのメール送信
SENDGRID_API_KEY=SG.xxx... FROM_EMAIL=noreply@example.com python send_email.py

# Slackへの通知
SLACK_WEBHOOK_URL=https://hooks.slack.com/... SLACK_CHANNEL=#alerts python notify.py
```

### 5. CI/CDパイプラインでの活用

**実行コマンド:**
```bash
# ステージング環境へのデプロイ
DEPLOY_ENV=staging APP_VERSION=v1.2.3 python deploy.py

# 本番環境への自動デプロイ（確認スキップ）
DEPLOY_ENV=production APP_VERSION=v1.2.3 SKIP_CONFIRMATION=true python deploy.py

# Dockerレジストリの設定
DOCKER_REGISTRY=my-registry.com DOCKER_USERNAME=user DOCKER_PASSWORD=pass python docker_push.py
```

### 6. セキュリティ設定

**実行コマンド:**
```bash
# JWT秘密鍵の設定
JWT_SECRET_KEY=your-secret-key TOKEN_EXPIRY=3600 python auth_server.py

# 暗号化キーの設定
ENCRYPTION_KEY=base64-encoded-key python encrypt_data.py

# OAuth設定
OAUTH_CLIENT_ID=client123 OAUTH_CLIENT_SECRET=secret456 OAUTH_REDIRECT_URI=http://localhost:8000/callback python oauth_app.py
```

## 高度なテクニック

### 1. シェルスクリプトでの環境変数管理

**実行コマンド:**
```bash
# 環境別実行スクリプトの作成と実行
cat > run_with_env.sh << 'EOF'
#!/bin/bash
ENV=${1:-local}
SCRIPT=${2:-app.py}

case $ENV in
  local)   env API_KEY=dev_key DATABASE_URL=postgres://localhost/dev_db python $SCRIPT ;;
  staging) env API_KEY=stage_key DATABASE_URL=postgres://stage.db.com/stage_db python $SCRIPT ;;
  prod)    env API_KEY=prod_key DATABASE_URL=postgres://prod.db.com/prod_db python $SCRIPT ;;
  *) echo "Unknown environment: $ENV" && exit 1 ;;
esac
EOF

# スクリプトに実行権限を付与
chmod +x run_with_env.sh

# 各環境での実行
./run_with_env.sh local app.py
./run_with_env.sh prod batch_processor.py
```

### 2. 環境変数のバリデーション

**最小限のPythonコード例:**
```python
# config.py
import os, sys
API_KEY = os.getenv('API_KEY') or sys.exit("API_KEY environment variable is required")
DATABASE_URL = os.getenv('DATABASE_URL') or sys.exit("DATABASE_URL environment variable is required")
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO')
```

**実行コマンド:**
```bash
# 必須環境変数付きで実行
API_KEY=sk-123 DATABASE_URL=postgres://localhost/db python config.py
```

### 3. 複数環境でのテスト実行

**実行コマンド:**
```bash
# 複数環境で同じテストを実行
for env in dev staging prod; do
  echo "Testing in $env environment..."
  API_KEY=${env}_key DATABASE_URL=postgres://${env}.db.com/db python test_suite.py
done

# 並列で複数環境テスト
API_KEY=dev_key DATABASE_URL=postgres://dev.db.com/db python test_suite.py &
API_KEY=stage_key DATABASE_URL=postgres://stage.db.com/db python test_suite.py &
wait
```

## 注意点とベストプラクティス

### 1. プロセス管理

**実行コマンド:**
```bash
# バックグラウンド実行での環境変数設定
WORKER_ID=1 API_KEY=key1 python worker.py &
WORKER_ID=2 API_KEY=key2 python worker.py &

# プロセスの管理
jobs  # 実行中のジョブ確認
kill %1  # ジョブ1を終了

# 環境変数を保持したままsudoで実行
sudo -E env API_KEY=$API_KEY python script.py
```

### 2. デバッグとトラブルシューティング

**実行コマンド:**
```bash
# 環境変数の確認
DEBUG_ENV=true API_KEY=secret python debug_env.py

# 特定の環境変数のみ確認
env | grep API_

# 環境変数を設定して詳細出力
set -x  # コマンド実行時の詳細表示
API_KEY=test DATABASE_URL=postgres://localhost/test python script.py
set +x  # 詳細表示を無効化
```

### 3. 実行時のTips

**実行コマンド:**
```bash
# 長い環境変数設定を読みやすく記述
API_KEY=very_long_api_key_here \
DATABASE_URL=postgresql://user:pass@database.example.com:5432/mydb \
LOG_LEVEL=DEBUG \
python script.py

# 環境変数をファイルから一括読み込み
set -a && source config.env && set +a && python script.py

# 一時的に環境変数を設定してすぐに削除
(API_KEY=temp_key python script.py)  # サブシェルで実行

# 複数のスクリプトで同じ環境変数を使用
export API_KEY=shared_key
export DATABASE_URL=postgres://localhost/shared_db
python script1.py
python script2.py
unset API_KEY DATABASE_URL
```

## 通常変数の指定も可能

環境変数と同じ構文で、通常の変数も指定できます：

**実行コマンド:**
```bash
# 通常変数の指定（環境変数ではない）
USER_NAME=john AGE=25 python script.py

# ファイルパスやオプションも同様に指定可能
INPUT_FILE=/path/to/input.txt OUTPUT_DIR=/tmp/output python process.py

# 数値や設定値
MAX_CONNECTIONS=100 TIMEOUT=30 python server.py
```

**注意点:**
- 通常変数はPythonコード内で `os.getenv()` を使って取得する必要があります
- システムの環境変数とは区別されます
- スクリプト実行時のみ有効で、システム全体には影響しません

## まとめ

コマンドラインでの環境変数指定は、以下の場面で特に威力を発揮します：

### 主要な活用場面
1. **開発・テスト環境**: 異なる設定での一時的な実行
2. **CI/CDパイプライン**: 自動化されたビルド・デプロイプロセス
3. **並列処理**: 同じスクリプトを異なる設定で同時実行
4. **環境切り替え**: 開発・ステージング・本番環境の切り替え
5. **デバッグ**: 本番環境での一時的な設定変更

### ベストプラクティス
- 環境変数のバリデーションを実装
- 適切なデフォルト値を設定
- 長いコマンドは改行で読みやすく記述
- サブシェルを活用して影響範囲を限定