Slide 1

Slide 1 text

ターミナル雑記 端末と和解せよ 発表者: すとんりばー

Slide 2

Slide 2 text

自己紹介

Slide 3

Slide 3 text

自己紹介 Twitter : @strvert GitHub : strvworks HN:すとんりばー 所属 :  苫小牧高専 情報科学・工学系 undefined年  ソフトウェアテクノロジー部, 情報処理同好会  LOCAL学生部 趣味 :  ArchLinux, Vim, C++, Python, 自鯖運用, 読書 Go 活動 :  プログラミング教育活動, 技術系アルバイト,  ゲーム開発サークル運営, イベント・勉強会運営 お気持ち :  僕ここにいて良いのかな?

Slide 4

Slide 4 text

質問 皆さんはターミナルエミュレータを利用した経験があ りますか?

Slide 5

Slide 5 text

質問 皆さんは普段ターミナルエミュレータを利用して生活 を送っていますか?

Slide 6

Slide 6 text

質問 では、ターミナルエミュレータとはそもそも何かを理 解していますか?

Slide 7

Slide 7 text

質問 では、ターミナルエミュレータとはそもそも何かを理 解していますか? なんとなくコマンドを打ち込んで応答してくれる物とし て見てしまいがちですが、その正体や持っている機 能について触れてみたいと思います。

Slide 8

Slide 8 text

ターミナルエミュレータとは

Slide 9

Slide 9 text

ターミナルエミュレータとは ターミナルエミュレータについて理解するために、こ のターミナルエミュレータという名前に注目してみま しょう。

Slide 10

Slide 10 text

ターミナルエミュレータとは ターミナルエミュレータについて理解するために、こ のターミナルエミュレータという名前に注目してみま しょう。 そもそもエミュレータというからには、何らかの元とな る物の動作を模倣したソフトウェアであるはずです。

Slide 11

Slide 11 text

ターミナルエミュレータとは 少しコンピュータの歴史を遡ってみると、以下のよう な機器が出てきます。

Slide 12

Slide 12 text

ターミナルエミュレータとは この機器は、1978年にDigital Equipment Corporation社が発売した、VT100という機種の当時 のデファクトスタンダードと なっていたターミナル(端末)です。 もちろん完全CUIで、私達の知るよ うな動画再生も音楽再生もできま せん。

Slide 13

Slide 13 text

ターミナルエミュレータとは しかしVT100には、それまでに普及していたターミナ ルと異なるいくつかの特徴がありました。

Slide 14

Slide 14 text

ターミナルエミュレータとは しかしVT100には、それまでに普及していた端末と異 なるいくつかの特徴がありました。 - 表示文字の点滅機能 - 反転表示機能 - 下線機能 - etc…     つまり、文字の装飾機能

Slide 15

Slide 15 text

ターミナルエミュレータとは これらの機能は今のGUIの世界から見れば大した ことのない機能ですが、完全なCUIの世界であった 当時としては、これは非常に革新的かつグラフィカ ルな機能として迎えられました。

Slide 16

Slide 16 text

ターミナルエミュレータとは VT100は様々な文字装飾機能などを搭載してい ましたが、これはVT100独自の機能ではなく、 ANSI X3.64(ANSI escape code)というANSI規格 による文字制御の規格に準拠したものでした。

Slide 17

Slide 17 text

ターミナルエミュレータとは しかし、VT100が広く普及したため、ANSI X3.64準拠 端末をVT100互換とすることも多くありました。

Slide 18

Slide 18 text

ターミナルエミュレータとは しかし、VT100が広く普及したため、ANSI X3.64準拠 端末をVT100互換とすることも多くありました。 そして実は、現代に存在するターミナルエミュレータ というのは、その多くがこのVT100の機能を模倣した ソフトウェア達なのです。

Slide 19

Slide 19 text

ターミナルエミュレータとは しかし、実機時代に普及した端末はVT100だけでは ありません。後継となる主な端末としてVT220, VT340といった端末も存在し、これらの機能の一部 も現代のターミナルエミュレータに取り込まれていま す。

Slide 20

Slide 20 text

ターミナルエミュレータとは さらに、現代においてはGUIのWMが普及したことか ら、複数のターミナルエミュレータのウィンドウを起動 して、同時に複数のターミナルにアクセスすることが 可能になっています。 これは実機時代にはできなかったことです。

Slide 21

Slide 21 text

ターミナルエミュレータとは 現在導入しやすく比較的知られているものの中で、VT100などの 端末に対する機能の互換性が特に高い端末をいくつか紹介しま す。 ● Linux ○ Xterm ○ Mlterm ● Windows ○ Mintty ○ RLogin ○ TeraTerm

Slide 22

Slide 22 text

ターミナルエミュレータとは なお、GUI環境よりも下の環境でUNIX系OSを操作 するときに起動する端末は、各OS毎に異なるエミュ レータ実装となっています。 ターミナルエミュレータ自体の誕生過程とどうしてあ のような形なのかなんとなくイメージが付きましたで しょうか?

Slide 23

Slide 23 text

ターミナルエミュレータ周辺の構成

Slide 24

Slide 24 text

周辺の構成 ターミナルエミュレータの起源についてざっくりとお話 しましたが、ターミナルエミュレータ周辺の技術的な 構成はどうなっているのでしょうか。

Slide 25

Slide 25 text

周辺の構成 ターミナルエミュレータ単体では普段行うような操作 は当然できず、その他多くのソフトウェアと相互に連 携が行われています。

Slide 26

Slide 26 text

周辺の構成 これは、GUI環境においてターミナルエミュレータとその他のソフト ウェアが連携して動作するにあたって組まれている構成の概略図 です。 あえて分割して描きましたが、 ターミナルエミュレータも当然CUIを 提供するGUIアプリケーションであるた め、WMの上に位置することになります。

Slide 27

Slide 27 text

周辺の構成 そして、ターミナルエミュレータを介したユーザーの入出力は、ター ミナルエミュレータ自体でコマンドの解釈や処理は一切行わず、そ のバイトデータがシェル に送信されます。 実際にカーネルへコマンドを渡したり、 システムの機能を利用したり結果を受け 取っているのはすべてシェルです。

Slide 28

Slide 28 text

周辺の構成 つまり、ターミナルエミュレータはあくまでも入力と出力そのものし か行っていないのです。橋渡しの描画役であって、自らコマンドの 処理を行うことはまず ありません。 では、先程紹介したようなグラフィカル な文字の装飾などはどのように行われて いるのでしょうか。

Slide 29

Slide 29 text

制御コード

Slide 30

Slide 30 text

制御コード ターミナルエミュレータが画面を描画するにあたって は、受動的にバイトデータを受け取ることだけが基本 となります。 その中で、様々な効果を利用するために用いられる のが制御コードです。

Slide 31

Slide 31 text

制御コード ターミナルエミュレータは、自分に渡されてきたバイト データを監視しています。 そして、データ中に特定の制御コードが認められる と、その制御コード自体は出力せず、制御コードに割 り当てられた動作を自ら行います。

Slide 32

Slide 32 text

制御コード 現在利用されている文字コード達の歴史をたどると それらの大本に位置しているのは、ご存知ASCIIコー ドです。

Slide 33

Slide 33 text

制御コード 現在知られているASCIIコードは このようなものです。

Slide 34

Slide 34 text

制御コード 現在知られているASCIIコードは このようなものです。 制御コードとして定義されて いる文字は、青色の部分に なります。 ※SPは現在はちょっと特殊

Slide 35

Slide 35 text

制御コード 「「そんなこと知ってるが??」」と思ったかもしれませ ん。 では、ASCIIコードが何の機器で利用するために策 定された文字コードであるかご存知でしょうか。

Slide 36

Slide 36 text

制御コード 実はASCIIコードは、本来コンピュータで利用することを想定して策 定されたものではなく、テレタイプという遠隔で文字を送信するタイ プライター のような機器で用いられる ものでした。

Slide 37

Slide 37 text

制御コード テレタイプは電動の機械式タイプライターであるため、計算機能は 持たず、遠隔地に存在する接続したテレタイプにセットされた紙に 機械的に印字を行うものでした。 遠隔地のテレタイプに対して 印字以外の改行や改ページな どの動作を命令するために、 制御コードが必要となったの です。

Slide 38

Slide 38 text

制御コード その視点で、ASCIIコードの制御コードをいくつか見てみましょう。 制御コード テレタイプにおける動作 現在の動作 エスケープコード SP 用紙を左に1文字分ずらす制御 “空白”を入力(非制御コード) - BS 用紙を右に1文字分ずらす制御 左1文字削除(制御コード) \b LF 用紙を上に1行分ずらす制御 次行に移動 \n CR 用紙を1番右へずらす制御 行頭に移動 \r OSによって改行コードが異なる事があるのはここが由来 Unix系はコンピュータに向けて最適化 (LF) Windowsはテレタイプ準拠(LFCR)

Slide 39

Slide 39 text

制御コード ASCIIコードの源流がテレタイプのようなものであることを考えれ ば、ターミナルエミュレータがあくまでも入力の受け取りと、渡され たバイトデータの適切な表示のみを行うソフトウェアであるというこ とがより直感的に理解できるかと思います。 この図はちょっと分け方が微妙

Slide 40

Slide 40 text

制御コード しかし、テレタイプが前述の完全電子式の端末やミ ニコンピュータなどに置きかえられ始めると、ASCIIに 定義された最低限の制御コードのみでは表現の幅 が足りなくなるようになりました。そこで、より拡張さ れた制御コードが登場しました。

Slide 41

Slide 41 text

エスケープシーケンス

Slide 42

Slide 42 text

エスケープシーケンス エスケープシーケンスとは、単一の制御コードではな く、特定の制御コードのパターンで端末に対して指示 を出すシーケンスのこと。

Slide 43

Slide 43 text

エスケープシーケンス 以下は、エスケープシーケンスの種類の一部です。実際にはもっ と多くの種類が存在します。 制御シーケンス(コード)名 開始コード 効果 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に関係する制御。ウィンドウ情報など。

Slide 44

Slide 44 text

エスケープシーケンス エスケープシーケンスは、新たな文字を追加すること なく制御コードを拡張できるよう策定されています。 そのため、ESC制御コードを先頭においたシーケン スで構成されます。

Slide 45

Slide 45 text

エスケープシーケンス 例えば、以下のようなエスケープシーケンスが存在します。 シーケンス 概要 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)

Slide 46

Slide 46 text

エスケープシーケンス シーケンス 概要(抜粋) 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を超越してくる

Slide 47

Slide 47 text

エスケープシーケンス シーケンス 概要(抜粋) CSI Ps1 ; Ps2 ' z Ps1 = 0 ロケータ報告を無効にする = 1 ロケータ報告を有効にする = 2 ワンショットモード。 Ps2 = 0 文字モード。2 と同じ。 = 1 ピクセルモード。位置をピクセル単位で報告する。 = 2 文字モード。位置を文字単位で報告する。 CSI ' | ウィンドウ上のロケータ (マウスカーソル)の位置、ボタン状態などを報告。ロケータ報告が 有効化されている必要がある。 戻り値が発生しはじめる 各ターミナルが対応しているかはともかく、本当に多くのエスケープシーケンスが 存在するので、見ると面白いです。 Xtermが対応している制御シーケンス : https://invisible-island.net/xterm/ctlseqs/ctlseqs.pdf

Slide 48

Slide 48 text

エスケープシーケンスの利用

Slide 49

Slide 49 text

エスケープシーケンスの利用 色々と紹介してきましたが、実際にCUIアプリケー ションを作成するにあたってエスケープシーケンスを どのように利用すればいいでしょうか。

Slide 50

Slide 50 text

エスケープシーケンスの利用 単純に端末に対して一方的な命令を送るものであれ ば、標準出力を行う関数等に文字を出力させるだけ で、ターミナルエミュレータが読み取って効果を発揮 してくれます。

Slide 51

Slide 51 text

エスケープシーケンスの利用 問題は結果を返すタイプのエスケープシーケンスで す。これらは値を返しますが、あくまでターミナルの 機能の中で動作するため、値はキーボードで入力し たときと同様の状態になります。

Slide 52

Slide 52 text

エスケープシーケンスの利用 通常、標準入力から値を受け取るには改行コードが 入力される必要があります。 これはターミナルインターフェイスが入力を行単位で 受け付けることが原因です。

Slide 53

Slide 53 text

エスケープシーケンスの利用 これは端末が入力を行単位で受け付けることが原因で す。端末は行単位で入力をバッファリングし、改行コード を検知して標準入力に渡すことで処理効率を向上させて います。 そして、このような入力状態のことをカノニカルモードと 言います。

Slide 54

Slide 54 text

エスケープシーケンスの利用 カノニカルモードに対して、バッファリングを行わず1文字 毎に入力を処理する状態のことを非カノニカルモードと 言います。

Slide 55

Slide 55 text

エスケープシーケンスの利用 例えば、以下のプログラムの各モードでの動作を見てみ ます。

Slide 56

Slide 56 text

エスケープシーケンスの利用 通常のカノニカルモードで実行すると、例え終端に指定 した文字が標準入力に現れても、改行コードが入力され るまで入力が渡されません。

Slide 57

Slide 57 text

エスケープシーケンスの利用 一方、非カノニカルモードで同様の関数を実行すると、 終端に指定した文字が入力されると瞬時に入力が確定 し、それまでの値を取得することができます。

Slide 58

Slide 58 text

エスケープシーケンスの利用 ここで、ターミナルエミュレータが標準入力置くだけ置い ていく戻り値をもう一度見てみます。 すると、値の最後にアルファベットがついていることがわ かります。これを終端文字に指定した上で、非カノニカル モードで値の取得を行えば、ユーザーが改行コードを入 力しなくても値が利用できることがわかります。

Slide 59

Slide 59 text

エスケープシーケンスの利用 このモードはターミナルエミュレータではなく、ターミナル セッション毎に定義されるtermios構造体の値を変更す る必要があります。 termios構造体へのアクセスはioctlシステムコールを用 いて行うことが出来ますが、より高レベル(笑)な というライブラリのtcgetattr()やtcsetattr()を 利用します。

Slide 60

Slide 60 text

エスケープシーケンスの利用 struct構造体は、以下のようなメンバが含まれています。 tcflag_t 型は4Byteの変数で、その32Bitの各ビットが対 応する設定のフラグになっています。

Slide 61

Slide 61 text

エスケープシーケンスの利用 例えばc_lflagの2ビット目を0にすれば、カノニカルモー ドから非カノニカルモードに変更することができます。

Slide 62

Slide 62 text

エスケープシーケンスの利用 ここではエスケープシーケンスの戻り値を利用するため に利用しましたが、termios構造体には他にも非常にに 多くの細かな設定が含まれています。 ある程度弄れるようになると、かなり柔軟にターミナルの 動きを制御できるようになります。

Slide 63

Slide 63 text

Sixel Graphics

Slide 64

Slide 64 text

Sixel Graphics ここまで、ターミナルエミュレータ自体にに実は豊富な機 能が搭載されていることを紹介してきましたが、まだCUI の域を出ないものでした。 しかし、このSixel Graphicsはそれを覆します。

Slide 65

Slide 65 text

Sixel Graphics Sixel Graphicsは以下のようなエスケープシーケンスに よって表される画像フォーマットです。 役割 シーケンス 詳細 Sixel開始 \x1bPq 開始シーケンス カラーパレット(可変長) #P1;P2;P3;P4;P5 P1:番号, P2:カラーモード P3~P5: 色指定 ピクセルデータ [いろんな文字] 後述

Slide 66

Slide 66 text

Sixel Graphics Sixel Graphicsのピクセルデータは、以下のような図の 縦に6(six)個並んだビットのパターンに対応した文字を並 べることで記述します。 そして、ピクセルデータ指定の前にカラーパレットに定義 した番号を指定することで色を選択します。

Slide 67

Slide 67 text

Sixel Graphics 結果、以下のようなシーケンスでターミナルに画像を表 示することができます。 Wikipediaより引用

Slide 68

Slide 68 text

Sixel Graphics Sixelで大きな画像を表現すると、こんなかんじになりま す。これで1つのエスケープシーケンスです!

Slide 69

Slide 69 text

Sixel Graphics どうでしょうか。ターミナルで文字のみならず画像まで表 示できてしまう。マウスのボタン状態も位置も取得できて しまう。 今回は紹介しませんでしたが、MIDIの音階を指定して音 楽を再生するシーケンスとかもある。

Slide 70

Slide 70 text

Sixel Graphics これはもうユビキタスターミナル エミュレータ社会の到来も近い のでは?????

Slide 71

Slide 71 text

実装例

Slide 72

Slide 72 text

実装例 さて皆さん、お気づきの方もいらっしゃるか もしれませんが、このスライドなにか違和感 がありませんか??

Slide 73

Slide 73 text

実装例 そう、皆さんが長々と見せられてきたこのス ライドの画面、実はターミナルエミュレータ の画面なのです!

Slide 74

Slide 74 text

実装例 このソフトウェアには、ざっくり次の機能があります。 機能 実装 指定ディレクトリのビットマップ画像を表示 Sixel Graphics 自動表示サイズフィッティング CSI 14;;tによるサイズ取得, termiosによる非カノニカルモード キャッシュによる読み込みの高速化 普通に書いた キーボード操作の受付 termiosによるエコー非有効化 非カノニカルモード

Slide 75

Slide 75 text

実装例 ちょっと時間が足りなかったので実装が間 に合いませんでしたが、本当はマウスによ る画面操作まで実装するつもりでした。

Slide 76

Slide 76 text

実装例 本当はソースコードを示して実装の詳細を 示そうと思ったのですが、スライドがすでに 84ページに達しているため、見たい人は GitHubで好きに見てください。 https://github.com/strvworks/slide-sixel

Slide 77

Slide 77 text

まとめ

Slide 78

Slide 78 text

まとめ さて、長々とお話しましたが、普段触ってい る(?)ターミナルが本当に多くの機能を搭載 してることを実感していただけたでしょうか。

Slide 79

Slide 79 text

まとめ 今回紹介できた機能はこれでも本当にごく一部で す。 もし興味を持ってくださった方がいたら、こちらの楽し い楽しいCUIアプリケーション(笑)の世界に飛び込ん できませんか?

Slide 80

Slide 80 text

参考ページ 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