Skip to content

pio device monitorOperation not supported by device で落ちる

初出: 2026-05-19

症状

非対話シェル(スクリプトから呼んだとき、subprocess 経由、CI 環境 など)で:

bash
pio device monitor --port /dev/cu.usbmodem83301 --baud 115200

を実行すると:

termios.error: (19, 'Operation not supported by device')

で落ちる。

原因(噛み砕き)

  • PlatformIO の monitor は中で pyserialminiterm を使っている
  • miniterm「キーボード入力を1文字ずつ捕まえてマイコンに送る」 ためにターミナルを raw モードに切り替える
  • raw モードへの切り替えは termios.tcgetattr() という UNIX のシステムコールが必要
  • このシステムコールは 本物の TTY(仮想端末)が割り当てられていないと失敗する
  • 普通にターミナルから打つときは TTY があるので問題ないが、スクリプトの中から subprocess.run(...) で呼ぶ とか バックグラウンドプロセスとして起動する とき TTY が無いので死ぬ

要するに 「PlatformIO monitor は対話的に使う前提のツールで、自動化からは呼べない」

対処

A. 普段の開発: そのままターミナルで実行する(推奨)

何も問題ない。

bash
pio device monitor

B. 起動直後のログだけサクッと取りたい

pyserial で直接読む小さなスクリプトを書く:

python
# scripts/serial-snapshot.py
import serial, time, sys

port = sys.argv[1] if len(sys.argv) > 1 else '/dev/cu.usbmodem83301'
s = serial.Serial(port, 115200, timeout=0.1)

# DTR/RTS をパタパタして手動リセット
s.dtr = False; s.rts = True;  time.sleep(0.1)
s.dtr = False; s.rts = False; time.sleep(0.1)

deadline = time.time() + 5
buf = b""
while time.time() < deadline:
    chunk = s.read(4096)
    if chunk:
        buf += chunk
        sys.stdout.buffer.write(chunk)
        sys.stdout.buffer.flush()

s.close()

使い方:

bash
python3 scripts/serial-snapshot.py

C. macOS 標準の screen を使う

screen も対話用だが TTY を強制割り当てするので起動は通る(ただしバックグラウンドからは結局使いにくい)。

bash
screen /dev/cu.usbmodem83301 115200
# 終了: Ctrl+A → K → y

D. tio (推奨される代替)

bash
brew install tio
tio /dev/cu.usbmodem83301

tio は色付き表示・ログファイル保存・自動再接続などが付いていて使い勝手が良い。

自動化したいときは

CI で「書き込んでログを取って assertion する」みたいなことをやりたい場合は ESP-IDF の idf.py monitor より、pyserial 直叩き の方が組み込みやすい。

ボードがフリーズしてないかチェックするだけなら、pyserialSerial.println の特定文字列が一定時間内に来るか見る、という形にする。

学び

  • 対話 UI 前提のツールを自動化に使おうとすると詰む — Web 開発でも vim を CI で呼ぼうとして同じ問題に当たる
  • そういうときは「ターミナルが要求している基本機能(TTY、stdin など)」を提供できるかを確認する
  • たいてい同じ仕事を ライブラリレイヤ(pyserial 等) で書き直せる

aieo-product / stack-chan project