terminal でカーソルを動かす方法
よくある手法として \r
でカーソルを行頭に戻すというのがあって、例えば以下のような感じにして進捗表示に棒を回したりするけど:
$ spinner=('-' '\' '|' '/')
$ for i in {1..100}; do
> echo -n "${spinner[$(($i % 4))]}"
> echo -ne '\r'
> sleep 0.1
> done
しかし、じゃあコレを縦に3つ並べて回したい、となった時に \r
だとどうしょうもないので、カーソルをもっと自由に動かす方法。
端末ごとに適切なエスケープシーケンスを吐いてやればカーソルを動かせる。 何が適切かは terminfo データベースに書いてある。
シェルからは tput
コマンドを使って名前から対応するものを出力できる。 ということで、縦に3つ並べるのはこうなる:
$ spinner=('-' '\' '|' '/')
$ for i in {1..100}; do
> echo "${spinner[$(($i % 4))]}"
> echo "${spinner[$(($i % 4))]}"
> echo "${spinner[$(($i % 4))]}"
> tput cuu 3
> sleep 0.1
> done
(tput cuu 3
でカーソルを3つ上に動かす。その他、何が出来るかは man terminfo
を後で読む。)
python だと curses
モジュールで同様のことが出来る:
import curses import sys import time SPINNER = list(r'-\|/') curses.setupterm() for i in range(100): print(SPINNER[i % 4]) print(SPINNER[i % 4]) print(SPINNER[i % 4]) sys.stdout.buffer.write(curses.tparm(curses.tigetstr('cuu'), 3)) sys.stdout.buffer.flush() time.sleep(0.1)