Linux の /proc と /dev は実際のディスク上にデータを持たない「仮想ファイルシステム」だ。Python からこれらを読み書きすることで、カーネルの情報を取得したり、デバイスを操作したりできる。
/proc:カーネル情報への窓
/proc はプロセスとカーネルの情報を公開する仮想ファイルシステムだ。ファイルを読むと、その瞬間のカーネルの状態が返される。
# CPU 情報を読む
with open("/proc/cpuinfo") as f:
for line in f:
if line.startswith("model name"):
print(line.strip())
break
# model name : Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
# メモリ情報を読む
with open("/proc/meminfo") as f:
for line in f:
if line.startswith(("MemTotal", "MemFree", "MemAvailable")):
print(line.strip())
これらのファイルは実際にはディスク上に存在せず、読み取り時にカーネルが動的に生成する。
/proc/[pid]:プロセスごとの情報
各プロセスは /proc/[pid]/ 以下に専用のディレクトリを持つ。
import os
pid = os.getpid() # 現在のプロセス ID
# コマンドライン引数
with open(f"/proc/{pid}/cmdline") as f:
cmdline = f.read().replace("\0", " ")
print(f"コマンド: {cmdline}")
# 環境変数
with open(f"/proc/{pid}/environ") as f:
env = f.read().split("\0")
for e in env[:3]: # 最初の 3 つだけ
print(e)
# ファイルディスクリプタ一覧
fd_dir = f"/proc/{pid}/fd"
for fd in os.listdir(fd_dir):
link = os.readlink(f"{fd_dir}/{fd}")
print(f"fd {fd} -> {link}")
/proc/self:自分自身への参照
/proc/self は常に現在のプロセスを指す特殊なシンボリックリンクだ。
import os
# PID を知らなくても自分の情報にアクセスできる
with open("/proc/self/status") as f:
for line in f:
if line.startswith(("Name:", "Pid:", "VmRSS:")):
print(line.strip())
# Name: python3
# Pid: 12345
# VmRSS: 28456 kB(実メモリ使用量)
/dev:デバイスへのアクセス
/dev はデバイスをファイルとして公開する。読み書きでデバイスを操作できる。
書き込んだデータを捨てる「ブラックホール」。読み込むと即座に EOF を返す。
読み込むと無限にゼロバイトを返す。メモリの初期化やファイルの埋め草に使う。
読み込むと暗号学的に安全な乱数を返す。
現在の端末デバイス。
import os
# /dev/urandom から乱数を読む
with open("/dev/urandom", "rb") as f:
random_bytes = f.read(16)
print(random_bytes.hex())
# 7a3b9c4d5e6f1a2b3c4d5e6f7a8b9c0d
# /dev/null に書き込む(捨てられる)
with open("/dev/null", "w") as f:
f.write("この文字列は消える")
# /dev/zero から読む
with open("/dev/zero", "rb") as f:
zeros = f.read(10)
print(list(zeros))
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
システム情報の取得例
/proc を使うと、psutil などの外部ライブラリなしでシステム情報を取得できる。
def get_load_average():
"""ロードアベレージを取得"""
with open("/proc/loadavg") as f:
parts = f.read().split()
return float(parts[0]), float(parts[1]), float(parts[2])
def get_uptime():
"""システム稼働時間を取得(秒)"""
with open("/proc/uptime") as f:
return float(f.read().split()[0])
def get_memory_usage():
"""メモリ使用状況を取得(KB)"""
info = {}
with open("/proc/meminfo") as f:
for line in f:
parts = line.split()
key = parts[0].rstrip(":")
value = int(parts[1])
info[key] = value
return info
print(f"Load: {get_load_average()}")
print(f"Uptime: {get_uptime() / 3600:.1f} hours")
mem = get_memory_usage()
used = mem["MemTotal"] - mem["MemAvailable"]
print(f"Memory: {used // 1024} MB / {mem['MemTotal'] // 1024} MB")
/proc への書き込み
一部の /proc ファイルは書き込み可能で、カーネルのパラメータを変更できる。
# IP フォワーディングを有効にする(要 root) echo 1 > /proc/sys/net/ipv4/ip_forward # ファイルディスクリプタの上限を確認 cat /proc/sys/fs/file-max
# Python から書き込む場合(要 root 権限)
def enable_ip_forward():
with open("/proc/sys/net/ipv4/ip_forward", "w") as f:
f.write("1")
注意点
/proc と /dev の構造は Linux 固有。macOS や Windows では使えない。移植性が必要なら psutil などのライブラリを使う。
/proc の出力フォーマットはカーネルバージョンで変わることがある。本番コードではエラーハンドリングを忘れずに。
他プロセスの情報や一部のシステム設定は root 権限が必要。
まとめ
カーネルとプロセスの情報を公開。読み取りでシステム状態を取得、書き込みでカーネルパラメータを変更
デバイスをファイルとして公開。null、zero、urandom などの特殊デバイスは便利ツールとして使える
これらの仮想ファイルシステムを理解すると、Linux システムの深い部分に Python からアクセスできるようになる。