bashのシェルスクリプトで、ターミナルのウィンドウサイズやカーソルの現在位置を取得させたいということがあったので、備忘で残しておく。
1. ターミナルのサイズを取得する
ターミナルのサイズを取得するのは簡単で、bashでcheckwinsizeが有効になっていれば$LINES、$COLUMNS変数に値が入る。
#!/bin/bash
shopt -s checkwinsize; (:;:)
echo $LINES # 行数
echo $COLUMNS # 横の文字数
ちなみに、数字は1から数えての数になっている。
2. カーソルの現在位置を取得する
現在のターミナル上のカーソル位置を取得する場合は、ANSIエスケープを利用する。
ANSIエスケープで「\e[6n
」を出力させると、「ESC[n;mR
」(キャレット記法だと「^[[n;mR
」)という出力で現在のカーソル位置を取得できる。
これはnが行数、mが列数になっている(ちなみに0から数えた数)。
スクリプト上で現在のカーソル位置を取得する場合、端末が払い出されない場合(パイプ越しに実行した場合)でも動作するよう、以下のようにttyを別に用意して数えるのがいいようだ。
# @brief: get cursor positon
# @return: $row $col
function __get_cursor_position() {
exec < /dev/tty
local OLD_STTY=$(stty -g)
stty raw -echo min 0
# get position data
echo -ne "\e[6n" > /dev/tty
IFS=';' read -r -d R -a POSITION
stty ${OLD_STTY}
# parse row and column
local POS_ROW=${POSITION[0]:2}
local POS_COL=${POSITION[1]}
echo ${POS_ROW} ${POS_COL}
}
上のような関数を設定しておけば、関数実行時にカーソル位置を取得することができる。