1
3

シェルスクリプトでエスケープシーケンスを使って端末情報を取得する方法

Last updated at Posted at 2024-02-19

はじめに

シェルスクリプトでエスケープシーケンスを使ってターミナルの情報(ウインドウサイズとかカーソル位置とか)を取得する方法の(個人的?)メモです。

report() {
  (                                  # trap EXITを使うためのサブシェル
    set -- "$1" "$(stty -g)"         # 現在の端末設定のバックアップ
    trap 'stty "$2"' EXIT            # サブシェル脱出時に端末設定を戻す
    # rawだとCTRL-Cできないしtimeやminも機能しないようなので-icanon
    stty -echo -icanon time 1 min 0  # エコーバックなしとその他の設定
    printf "$1" >/dev/tty            # 問い合わせのエスケープシーケンスを端末に出力
    dd count=1 2>/dev/null           # 端末からの応答を読み取って標準出力に出力
  ) </dev/tty                        # 標準入力を端末に明示的に指定
}

# ウインドウサイズの取得
report '\033[18t' | od -An -a
#  esc   [   8   ;   4   4   ;   1   4   6   t

# カーソル位置の取得
report '\033[6n' | od -An -a
#  esc   [   1   5   ;   1   R

他に read -d 最後の文字 とか使ってデータを読んでいるのも見つかりましたが、対応してないシェルがあったり最後の文字を指定するのは汎用的ではないので、良さげな感じのコードで書きました。

なお、普通は tput lines とか tput cols とかを使ったほうが簡単です。$LINES$COLUMNS を使う方法もあります。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3