その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

expectコマンドを使ってシリアル接続で非対話的にコマンドを流し込む

シリアル接続でコマンドを実行する際は cu コマンドや screen コマンドなどでシリアルコンソールに接続して対話的にコマンドを実行することになると思うんですが,しかし「一定周期ごとにシリアルでコマンドを実行して結果を取得したい」みたいなときに対話モードだとだるいわけです.
というわけで expect の出番です.以下のように expect コマンドを利用すると非対話的にシリアルにコマンドを流し込むことができます. expect コマンドについてはこちらを参照されたい:
expect(1) - Linux man page

expect -c "
  spawn cu -l ${TTY} -s 9600
  send \"AT+CGREG=2\\n\"
  expect \"OK\"
  send \"AT+CGREG?\\n\"
  expect \"+CGREG:\"
  exit 0
"

これは

soracom.zendesk.com

にあるLACとCIDを取得するATコマンドの例ですが,こうしてやることで非対話的にATコマンドを流し込むことができます.

while :
do
  RESULT="$(expect -c "
    spawn cu -l ${TTY} -s 9600
    send \"AT+CGREG=2\\n\"
    expect \"OK\"
    send \"AT+CGREG?\\n\"
    expect \"+CGREG:\"
    exit 0
  " | grep '^+CGREG:')"

  PCRE_LAC_CID_PATTERN='"(.+?)",\s*"(.+?)"'
  LAC="$(echo "$RESULT" | perl -ale "/${PCRE_LAC_CID_PATTERN}/; print \$1")"
  CID="$(echo "$RESULT" | perl -ale "/${PCRE_LAC_CID_PATTERN}/; print \$2")"

  echo "{\"LAC\":$LAC, \"CID\":$CID}"

  sleep 60
done

例えばこうしてやると1分ごとにcell locationが取れて便利.expect コマンド最高!!!! (しかし難しい)