Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ターミナル雑記
Search
stonriver
February 23, 2019
Programming
2
1.2k
ターミナル雑記
stonriver
February 23, 2019
Tweet
Share
More Decks by stonriver
See All by stonriver
中規模イベントに急造で変なネットワークを構築する
strvworks
1
750
並行処理入門 -Goで遊ぶ-
strvworks
0
220
お手軽金盾体験
strvworks
1
690
Kosen_LT_ONLINEのおしらせ
strvworks
0
72
Minecraft概論
strvworks
0
300
日本列島の移動速度に関する考察
strvworks
1
120
PythonにおけるGUIフレームワークのはなし
strvworks
0
310
快適な読書環境のご提案
strvworks
0
110
テクノ手芸
strvworks
0
62
Other Decks in Programming
See All in Programming
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
330
HTTP compression in PHP and Symfony apps
dunglas
2
1.7k
tidymodelsによるtidyな生存時間解析 / Japan.R2024
dropout009
1
770
Mermaid x AST x 生成AI = コードとドキュメントの完全同期への道
shibuyamizuho
0
160
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
170
talk-with-local-llm-with-web-streams-api
kbaba1001
0
180
「とりあえず動く」コードはよい、「読みやすい」コードはもっとよい / Code that 'just works' is good, but code that is 'readable' is even better.
mkmk884
3
270
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
260
StarlingMonkeyを触ってみた話 - 2024冬
syumai
3
270
コンテナをたくさん詰め込んだシステムとランタイムの変化
makihiro
1
130
fs2-io を試してたらバグを見つけて直した話
chencmd
0
230
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
210
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.6k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.3k
Making the Leap to Tech Lead
cromwellryan
133
9k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Being A Developer After 40
akosma
87
590k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Agile that works and the tools we love
rasmusluckow
328
21k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
Transcript
ターミナル雑記 端末と和解せよ 発表者: すとんりばー
自己紹介
自己紹介 Twitter : @strvert GitHub : strvworks HN:すとんりばー 所属 :
苫小牧高専 情報科学・工学系 undefined年 ソフトウェアテクノロジー部, 情報処理同好会 LOCAL学生部 趣味 : ArchLinux, Vim, C++, Python, 自鯖運用, 読書 Go 活動 : プログラミング教育活動, 技術系アルバイト, ゲーム開発サークル運営, イベント・勉強会運営 お気持ち : 僕ここにいて良いのかな?
質問 皆さんはターミナルエミュレータを利用した経験があ りますか?
質問 皆さんは普段ターミナルエミュレータを利用して生活 を送っていますか?
質問 では、ターミナルエミュレータとはそもそも何かを理 解していますか?
質問 では、ターミナルエミュレータとはそもそも何かを理 解していますか? なんとなくコマンドを打ち込んで応答してくれる物とし て見てしまいがちですが、その正体や持っている機 能について触れてみたいと思います。
ターミナルエミュレータとは
ターミナルエミュレータとは ターミナルエミュレータについて理解するために、こ のターミナルエミュレータという名前に注目してみま しょう。
ターミナルエミュレータとは ターミナルエミュレータについて理解するために、こ のターミナルエミュレータという名前に注目してみま しょう。 そもそもエミュレータというからには、何らかの元とな る物の動作を模倣したソフトウェアであるはずです。
ターミナルエミュレータとは 少しコンピュータの歴史を遡ってみると、以下のよう な機器が出てきます。
ターミナルエミュレータとは この機器は、1978年にDigital Equipment Corporation社が発売した、VT100という機種の当時 のデファクトスタンダードと なっていたターミナル(端末)です。 もちろん完全CUIで、私達の知るよ うな動画再生も音楽再生もできま せん。
ターミナルエミュレータとは しかしVT100には、それまでに普及していたターミナ ルと異なるいくつかの特徴がありました。
ターミナルエミュレータとは しかしVT100には、それまでに普及していた端末と異 なるいくつかの特徴がありました。 - 表示文字の点滅機能 - 反転表示機能 - 下線機能 -
etc… つまり、文字の装飾機能
ターミナルエミュレータとは これらの機能は今のGUIの世界から見れば大した ことのない機能ですが、完全なCUIの世界であった 当時としては、これは非常に革新的かつグラフィカ ルな機能として迎えられました。
ターミナルエミュレータとは VT100は様々な文字装飾機能などを搭載してい ましたが、これはVT100独自の機能ではなく、 ANSI X3.64(ANSI escape code)というANSI規格 による文字制御の規格に準拠したものでした。
ターミナルエミュレータとは しかし、VT100が広く普及したため、ANSI X3.64準拠 端末をVT100互換とすることも多くありました。
ターミナルエミュレータとは しかし、VT100が広く普及したため、ANSI X3.64準拠 端末をVT100互換とすることも多くありました。 そして実は、現代に存在するターミナルエミュレータ というのは、その多くがこのVT100の機能を模倣した ソフトウェア達なのです。
ターミナルエミュレータとは しかし、実機時代に普及した端末はVT100だけでは ありません。後継となる主な端末としてVT220, VT340といった端末も存在し、これらの機能の一部 も現代のターミナルエミュレータに取り込まれていま す。
ターミナルエミュレータとは さらに、現代においてはGUIのWMが普及したことか ら、複数のターミナルエミュレータのウィンドウを起動 して、同時に複数のターミナルにアクセスすることが 可能になっています。 これは実機時代にはできなかったことです。
ターミナルエミュレータとは 現在導入しやすく比較的知られているものの中で、VT100などの 端末に対する機能の互換性が特に高い端末をいくつか紹介しま す。 • Linux ◦ Xterm ◦ Mlterm
• Windows ◦ Mintty ◦ RLogin ◦ TeraTerm
ターミナルエミュレータとは なお、GUI環境よりも下の環境でUNIX系OSを操作 するときに起動する端末は、各OS毎に異なるエミュ レータ実装となっています。 ターミナルエミュレータ自体の誕生過程とどうしてあ のような形なのかなんとなくイメージが付きましたで しょうか?
ターミナルエミュレータ周辺の構成
周辺の構成 ターミナルエミュレータの起源についてざっくりとお話 しましたが、ターミナルエミュレータ周辺の技術的な 構成はどうなっているのでしょうか。
周辺の構成 ターミナルエミュレータ単体では普段行うような操作 は当然できず、その他多くのソフトウェアと相互に連 携が行われています。
周辺の構成 これは、GUI環境においてターミナルエミュレータとその他のソフト ウェアが連携して動作するにあたって組まれている構成の概略図 です。 あえて分割して描きましたが、 ターミナルエミュレータも当然CUIを 提供するGUIアプリケーションであるた め、WMの上に位置することになります。
周辺の構成 そして、ターミナルエミュレータを介したユーザーの入出力は、ター ミナルエミュレータ自体でコマンドの解釈や処理は一切行わず、そ のバイトデータがシェル に送信されます。 実際にカーネルへコマンドを渡したり、 システムの機能を利用したり結果を受け 取っているのはすべてシェルです。
周辺の構成 つまり、ターミナルエミュレータはあくまでも入力と出力そのものし か行っていないのです。橋渡しの描画役であって、自らコマンドの 処理を行うことはまず ありません。 では、先程紹介したようなグラフィカル な文字の装飾などはどのように行われて いるのでしょうか。
制御コード
制御コード ターミナルエミュレータが画面を描画するにあたって は、受動的にバイトデータを受け取ることだけが基本 となります。 その中で、様々な効果を利用するために用いられる のが制御コードです。
制御コード ターミナルエミュレータは、自分に渡されてきたバイト データを監視しています。 そして、データ中に特定の制御コードが認められる と、その制御コード自体は出力せず、制御コードに割 り当てられた動作を自ら行います。
制御コード 現在利用されている文字コード達の歴史をたどると それらの大本に位置しているのは、ご存知ASCIIコー ドです。
制御コード 現在知られているASCIIコードは このようなものです。
制御コード 現在知られているASCIIコードは このようなものです。 制御コードとして定義されて いる文字は、青色の部分に なります。 ※SPは現在はちょっと特殊
制御コード 「「そんなこと知ってるが??」」と思ったかもしれませ ん。 では、ASCIIコードが何の機器で利用するために策 定された文字コードであるかご存知でしょうか。
制御コード 実はASCIIコードは、本来コンピュータで利用することを想定して策 定されたものではなく、テレタイプという遠隔で文字を送信するタイ プライター のような機器で用いられる ものでした。
制御コード テレタイプは電動の機械式タイプライターであるため、計算機能は 持たず、遠隔地に存在する接続したテレタイプにセットされた紙に 機械的に印字を行うものでした。 遠隔地のテレタイプに対して 印字以外の改行や改ページな どの動作を命令するために、 制御コードが必要となったの です。
制御コード その視点で、ASCIIコードの制御コードをいくつか見てみましょう。 制御コード テレタイプにおける動作 現在の動作 エスケープコード SP 用紙を左に1文字分ずらす制御 “空白”を入力(非制御コード) -
BS 用紙を右に1文字分ずらす制御 左1文字削除(制御コード) \b LF 用紙を上に1行分ずらす制御 次行に移動 \n CR 用紙を1番右へずらす制御 行頭に移動 \r OSによって改行コードが異なる事があるのはここが由来 Unix系はコンピュータに向けて最適化 (LF) Windowsはテレタイプ準拠(LFCR)
制御コード ASCIIコードの源流がテレタイプのようなものであることを考えれ ば、ターミナルエミュレータがあくまでも入力の受け取りと、渡され たバイトデータの適切な表示のみを行うソフトウェアであるというこ とがより直感的に理解できるかと思います。 この図はちょっと分け方が微妙
制御コード しかし、テレタイプが前述の完全電子式の端末やミ ニコンピュータなどに置きかえられ始めると、ASCIIに 定義された最低限の制御コードのみでは表現の幅 が足りなくなるようになりました。そこで、より拡張さ れた制御コードが登場しました。
エスケープシーケンス
エスケープシーケンス エスケープシーケンスとは、単一の制御コードではな く、特定の制御コードのパターンで端末に対して指示 を出すシーケンスのこと。
エスケープシーケンス 以下は、エスケープシーケンスの種類の一部です。実際にはもっ と多くの種類が存在します。 制御シーケンス(コード)名 開始コード 効果 ESCシーケンス \e, \033, \x1b
全般的な制御。また、あらゆるシーケンスの開 始に含まれる。ASCIIに存在。 CSIシーケンス ESC + [ , ( \x1b[ ) Control Sequence Introducer 様々な端末コントロール、情報取得 DCSシーケンス ESC + P, ( \x1bP) Device Control String OSCシーケンス ESC + ], (\x1b]) Operating System Command OSに関係する制御。ウィンドウ情報など。
エスケープシーケンス エスケープシーケンスは、新たな文字を追加すること なく制御コードを拡張できるよう策定されています。 そのため、ESC制御コードを先頭においたシーケン スで構成されます。
エスケープシーケンス 例えば、以下のようなエスケープシーケンスが存在します。 シーケンス 概要 CSI Ps A カーソルを Ps 行上に移動する。
CSI Ps B カーソルを Ps 行下に移動する。 CSI Ps1 m 以降の出力背景をPs1 に指定した色に変更。 (赤=41, 緑=42, …..) CSI Ps c 端末特性を報告する。これを見ると何に準拠しているかわかる ESC # 8 画面を全部Eで埋める (描画範囲とかのテストに使うらしい ) シェルで試す例: for i in {47..40}; do echo -e ’\x1b[’${i}’m’; done // (PARTY)
エスケープシーケンス シーケンス 概要(抜粋) CSI Ps1 ; Ps2 ; Ps3 t
Ps1 = 1 ウィンドウを通常表示状態にする。 = 2 ウィンドウを最小化する。 = 3 ウィンドウ位置を Ps2, Ps3 に移動する。 = 4 ウィンドウサイズを高さ Ps2 ドット, 幅 Ps3 ドットに変更する。 = 5 ウィンドウを前面に移動する。 = 6 ウィンドウを背面に移動する。 = 10 端末のフルスクリーンモードを変更する。 Ps2 = 0 フルスクリーン状態を解除する = 1 フルスクリーン状態にする = 2 フルスクリーン状態を変更する(トグル) シェルで試す例: echo -e ’\x1b[3;100;100t’ // (ウィンドウを左上から100, 100に移動) echo -e ’\x1b[10;1;t’ // (ウィンドウをフルスクリーンに!) だんだんCUIを超越してくる
エスケープシーケンス シーケンス 概要(抜粋) CSI Ps1 ; Ps2 ' z Ps1
= 0 ロケータ報告を無効にする = 1 ロケータ報告を有効にする = 2 ワンショットモード。 Ps2 = 0 文字モード。2 と同じ。 = 1 ピクセルモード。位置をピクセル単位で報告する。 = 2 文字モード。位置を文字単位で報告する。 CSI ' | ウィンドウ上のロケータ (マウスカーソル)の位置、ボタン状態などを報告。ロケータ報告が 有効化されている必要がある。 戻り値が発生しはじめる 各ターミナルが対応しているかはともかく、本当に多くのエスケープシーケンスが 存在するので、見ると面白いです。 Xtermが対応している制御シーケンス : https://invisible-island.net/xterm/ctlseqs/ctlseqs.pdf
エスケープシーケンスの利用
エスケープシーケンスの利用 色々と紹介してきましたが、実際にCUIアプリケー ションを作成するにあたってエスケープシーケンスを どのように利用すればいいでしょうか。
エスケープシーケンスの利用 単純に端末に対して一方的な命令を送るものであれ ば、標準出力を行う関数等に文字を出力させるだけ で、ターミナルエミュレータが読み取って効果を発揮 してくれます。
エスケープシーケンスの利用 問題は結果を返すタイプのエスケープシーケンスで す。これらは値を返しますが、あくまでターミナルの 機能の中で動作するため、値はキーボードで入力し たときと同様の状態になります。
エスケープシーケンスの利用 通常、標準入力から値を受け取るには改行コードが 入力される必要があります。 これはターミナルインターフェイスが入力を行単位で 受け付けることが原因です。
エスケープシーケンスの利用 これは端末が入力を行単位で受け付けることが原因で す。端末は行単位で入力をバッファリングし、改行コード を検知して標準入力に渡すことで処理効率を向上させて います。 そして、このような入力状態のことをカノニカルモードと 言います。
エスケープシーケンスの利用 カノニカルモードに対して、バッファリングを行わず1文字 毎に入力を処理する状態のことを非カノニカルモードと 言います。
エスケープシーケンスの利用 例えば、以下のプログラムの各モードでの動作を見てみ ます。
エスケープシーケンスの利用 通常のカノニカルモードで実行すると、例え終端に指定 した文字が標準入力に現れても、改行コードが入力され るまで入力が渡されません。
エスケープシーケンスの利用 一方、非カノニカルモードで同様の関数を実行すると、 終端に指定した文字が入力されると瞬時に入力が確定 し、それまでの値を取得することができます。
エスケープシーケンスの利用 ここで、ターミナルエミュレータが標準入力置くだけ置い ていく戻り値をもう一度見てみます。 すると、値の最後にアルファベットがついていることがわ かります。これを終端文字に指定した上で、非カノニカル モードで値の取得を行えば、ユーザーが改行コードを入 力しなくても値が利用できることがわかります。
エスケープシーケンスの利用 このモードはターミナルエミュレータではなく、ターミナル セッション毎に定義されるtermios構造体の値を変更す る必要があります。 termios構造体へのアクセスはioctlシステムコールを用 いて行うことが出来ますが、より高レベル(笑)な <termios.h>というライブラリのtcgetattr()やtcsetattr()を 利用します。
エスケープシーケンスの利用 struct構造体は、以下のようなメンバが含まれています。 tcflag_t 型は4Byteの変数で、その32Bitの各ビットが対 応する設定のフラグになっています。
エスケープシーケンスの利用 例えばc_lflagの2ビット目を0にすれば、カノニカルモー ドから非カノニカルモードに変更することができます。
エスケープシーケンスの利用 ここではエスケープシーケンスの戻り値を利用するため に利用しましたが、termios構造体には他にも非常にに 多くの細かな設定が含まれています。 ある程度弄れるようになると、かなり柔軟にターミナルの 動きを制御できるようになります。
Sixel Graphics
Sixel Graphics ここまで、ターミナルエミュレータ自体にに実は豊富な機 能が搭載されていることを紹介してきましたが、まだCUI の域を出ないものでした。 しかし、このSixel Graphicsはそれを覆します。
Sixel Graphics Sixel Graphicsは以下のようなエスケープシーケンスに よって表される画像フォーマットです。 役割 シーケンス 詳細 Sixel開始 \x1bPq
開始シーケンス カラーパレット(可変長) #P1;P2;P3;P4;P5 P1:番号, P2:カラーモード P3~P5: 色指定 ピクセルデータ [いろんな文字] 後述
Sixel Graphics Sixel Graphicsのピクセルデータは、以下のような図の 縦に6(six)個並んだビットのパターンに対応した文字を並 べることで記述します。 そして、ピクセルデータ指定の前にカラーパレットに定義 した番号を指定することで色を選択します。
Sixel Graphics 結果、以下のようなシーケンスでターミナルに画像を表 示することができます。 Wikipediaより引用
Sixel Graphics Sixelで大きな画像を表現すると、こんなかんじになりま す。これで1つのエスケープシーケンスです!
Sixel Graphics どうでしょうか。ターミナルで文字のみならず画像まで表 示できてしまう。マウスのボタン状態も位置も取得できて しまう。 今回は紹介しませんでしたが、MIDIの音階を指定して音 楽を再生するシーケンスとかもある。
Sixel Graphics これはもうユビキタスターミナル エミュレータ社会の到来も近い のでは?????
実装例
実装例 さて皆さん、お気づきの方もいらっしゃるか もしれませんが、このスライドなにか違和感 がありませんか??
実装例 そう、皆さんが長々と見せられてきたこのス ライドの画面、実はターミナルエミュレータ の画面なのです!
実装例 このソフトウェアには、ざっくり次の機能があります。 機能 実装 指定ディレクトリのビットマップ画像を表示 Sixel Graphics 自動表示サイズフィッティング CSI 14;;tによるサイズ取得,
termiosによる非カノニカルモード キャッシュによる読み込みの高速化 普通に書いた キーボード操作の受付 termiosによるエコー非有効化 非カノニカルモード
実装例 ちょっと時間が足りなかったので実装が間 に合いませんでしたが、本当はマウスによ る画面操作まで実装するつもりでした。
実装例 本当はソースコードを示して実装の詳細を 示そうと思ったのですが、スライドがすでに 84ページに達しているため、見たい人は GitHubで好きに見てください。 https://github.com/strvworks/slide-sixel
まとめ
まとめ さて、長々とお話しましたが、普段触ってい る(?)ターミナルが本当に多くの機能を搭載 してることを実感していただけたでしょうか。
まとめ 今回紹介できた機能はこれでも本当にごく一部で す。 もし興味を持ってくださった方がいたら、こちらの楽し い楽しいCUIアプリケーション(笑)の世界に飛び込ん できませんか?
参考ページ Sixel: https://www.vt100.net/docs/vt3xx-gp/chapter14.html xterm control sequence: https://invisible-island.net/xterm/ctlseqs/ctlseqs.pdf termios: https://linuxjm.osdn.jp/html/LDP_man-pages/man3/termios.3.html