なぜ、いまだにシェルスクリプトで消耗しているのか
Linux上の定常作業や自動化タスクにおいて、Bashなどのシェルスクリプトは便利だが、少し複雑な処理(JSONパース、API連携、並列処理など)を行おうとすると、途端に可読性が低下し、メンテナンスが困難になる。
Pythonで書き直したいところだが、サードパーティ製ライブラリ(requestsやpsutilなど)に依存すると、実行環境ごとにpip installやvenvの構築が必要になり、ポータビリティが失われる。
このジレンマを解決するのが、**PEP 723(Inline script metadata)と、Rust製の超高速Pythonパッケージマネージャーuv**の組み合わせだ。これを使えば、スクリプト内に依存関係を記述し、完全に「単一ファイル」でポータブルに実行できる。
現代の最適解:PEP 723 + uv
PEP 723は、Pythonスクリプトの中に、そのスクリプトが必要とする依存ライブラリやPythonの要求バージョンをコメント形式で直接埋め込める仕様だ。
そして、Astral社が開発するuvを使用すれば、実行時にその依存関係を自動的かつ高速に一時環境へインストールし、スクリプトを実行してくれる。ホスト環境を汚すことは一切ない。
実践:システム情報を収集して通知するモダンスクリプト
以下は、Linuxのシステムリソース情報を監視し、サードパーティライブラリであるpsutilとrequestsを使用して整形・送信する実用的な自動化スクリプトだ。
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "psutil>=5.9.0",
# "requests>=2.31.0",
# ]
# ///
import os
import socket
import psutil
import requests
def get_system_stats():
cpu_usage = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory()
disk = psutil.disk_usage('/')
return {
"hostname": socket.gethostname(),
"cpu": f"{cpu_usage}%",
"memory": f"{memory.percent}% (Used: {memory.used // (1024**2)}MB / Total: {memory.total // (1024**2)}MB)",
"disk": f"{disk.percent}%"
}
def send_to_webhook(stats):
# 環境変数からWebhook URLを取得
webhook_url = os.getenv("MONITOR_WEBHOOK_URL")
if not webhook_url:
print("Error: MONITOR_WEBHOOK_URL environment variable is not set.")
print(f"[DEBUG] Stats: {stats}")
return
payload = {
"text": f"🚨 **System Monitor Alert - {stats['hostname']}** 🚨\n"
f"- **CPU Usage:** {stats['cpu']}\n"
f"- **Memory Usage:** {stats['memory']}\n"
f"- **Disk Usage:** {stats['disk']}"
}
response = requests.post(webhook_url, json=payload)
if response.status_code in (200, 204):
print("Successfully sent system stats to webhook.")
else:
print(f"Failed to send. Status: {response.status_code}, Response: {response.text}")
if __name__ == "__main__":
stats = get_system_stats()
send_to_webhook(stats)
このスクリプトの何が革命的なのか?
スクリプトの先頭部分に注目してほしい。
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "psutil>=5.9.0",
# "requests>=2.31.0",
# ]
# ///
これがPEP 723で規定されたメタデータだ。
このスクリプト(名前を monitor.py とする)を実行するにあたり、事前に pip install を行う必要は一切ない。
以下のコマンドを実行するだけで自動的に実行環境が構築される。
# uvのインストール(未導入の場合のみ、一瞬で完了する)
curl -LsSf https://astral.sh/uv/install.sh | sh
# スクリプトの実行
uv run monitor.py
uv は、スクリプト内のメタデータを自動で解析し、必要なライブラリを隔離された一時的なキャッシュ領域にロードして、即座にスクリプトを実行する。2回目以降の実行は、キャッシュが効くためミリ秒単位で超高速に起動する。
実務における3大メリット
-
「環境が壊れる」問題からの完全な解放
システム全体のPython(System Python)やグローバル環境にライブラリをインストールしないため、OSのパッケージ管理を汚染するリスクがゼロになる。 -
圧倒的なポータビリティ
Gitリポジトリにこの1ファイルをコミットしておくだけで、他のLinuxサーバーでも、uv runさえ叩けば全く同じように動作する。requirements.txtもpyproject.tomlも不要だ。 -
Cronとの相性の良さ
Cronなどのジョブスケジューラから呼び出す際も、仮想環境の有効化(source venv/bin/activate)のような冗長な前処理が不要になる。
# Crontabでの設定例
0 * * * * export MONITOR_WEBHOOK_URL="https://your-webhook-url" && /usr/local/bin/uv run /path/to/monitor.py
結論
これからのLinux自動化は、「書きづらいシェルスクリプト」か「管理が面倒なPythonプロジェクト」かという二者択一ではない。
PEP 723とuvによる**「単一ファイル完結型のモダンPythonスクリプト」**こそが、これからのインフラ・開発運用のデファクトスタンダードである。今すぐ手元のスクリプトをこの構成に書き換え、運用の手間を最小限に抑えるべきだ。