Shell、Terminal、TTY、PTYは、いずれもコマンドライン操作に関係しますが、同じものではありません。全体を一言で表すと、次のようになります。
ユーザー
↓ キーボード入力
ターミナルエミュレーター
↓ 端末デバイスを提供
TTY / PTY
↓ 入出力を伝える
Shell
↓ コマンドを解釈してプログラムを起動
カーネル / アプリケーション1. Shellとは何か#
Shellは、ユーザーが入力したコマンドを解釈し、プログラムを起動するコマンドインタープリターです。
ls -l
cd Desktop
python main.py代表的なShellには、次のものがあります。
| Shell | 特徴 |
|---|---|
sh | Unixで広く使われた基本的なShell |
bash | Linuxで非常によく使われるShell |
zsh | macOSの標準Shellとしても使われる |
fish | 対話操作を重視した現代的なShell |
| PowerShell | Windowsで広く使われるShell |
Shellは、コマンドの実行だけでなく、変数、パイプ、リダイレクト、ワイルドカード展開、スクリプトも処理します。
cat a.txt | grep hello > result.txtこの例の|と>は、catやgrepが解釈するものではなく、Shellがコマンドを実行する前に処理します。
bash、zsh、fishは文法、組み込みコマンド、補完、対話的な使い勝手が異なります。しかし、いずれもShell、つまりコマンドインタープリターです。2. ターミナルエミュレーターとは何か#
ターミナルエミュレーターは、ユーザーが見るウィンドウと、キーボード入力やプログラム出力を扱うアプリケーションです。
macOS Terminal
iTerm2
Windows Terminal
GNOME Terminal
Konsole
Alacritty
Kitty
WezTermターミナルエミュレーター自体はShellではありません。主な役割は次のとおりです。
- 文字を表示する。
- キーボード入力を受け取る。
- プログラムの出力を表示する。
- 伝統的な端末デバイスの動作をエミュレートする。
- Shellを起動する。
たとえばmacOSのTerminalを開くと、内部でzshが起動します。Windows TerminalではPowerShellやWSLのbashが起動することがあります。つまり、ターミナルエミュレーターはウィンドウ、Shellはその中で動くコマンドインタープリターです。
3. TTYとは何か#
TTYは、もともと**Teletypewriter(テレタイプ端末)**を意味します。初期のコンピューターでは、タイプライターのような装置から文字を入力し、結果を文字で受け取っていました。
物理的なテレタイプ端末が使われなくなった後も、Unix/Linuxは端末デバイスを表す抽象的なインターフェースとしてTTYという概念を残しています。
/dev/tty
/dev/tty1
/dev/tty2
/dev/pts/0
/dev/pts/1/dev/tty1や/dev/tty2は、Linuxの仮想コンソールを表すことが多いデバイスです。Ctrl + Alt + F1などで切り替えられる黒いログイン画面は、物理端末ではありませんが、TTYインターフェースを使います。
4. PTYとは何か#
グラフィカルなターミナルエミュレーターでShellを使うとき、多くの場合は物理TTYではなくPTY(Pseudo Terminal、疑似端末)を利用します。
PTYは、次の2つの端点からなる仮想デバイスです。
PTY master ↔ PTY slave典型的な関係は次のとおりです。
ターミナルエミュレーター
↓
PTY master
↓
PTY slave
↓
ShellターミナルエミュレーターはPTY masterを通じて入力を送り、ShellやプログラムはPTY slaveを端末として利用します。Shellから見ると、実際の端末に接続しているように見えます。
tty出力が/dev/pts/0なら、そのShellが疑似端末へ接続されていることを示します。
5. コマンド実行時の流れ#
macOS Terminalで次のコマンドを入力するとします。
echo hello処理の流れは次のとおりです。
- Terminal.appがウィンドウを開く。
- Terminal.appがPTYを作成する。
- Terminal.appが
zshを起動する。 - ユーザーが
echo helloを入力する。 zshがコマンドを解析する。zshがechoを実行する。echoがhelloを出力する。- 出力がPTYを通ってTerminal.appへ戻る。
- Terminal.appがウィンドウへ
helloを表示する。
6. 用語を比較する#
| 用語 | 本質 | 例 |
|---|---|---|
| Shell | コマンドを解釈して実行するプログラム | bash、zsh、fish |
| Terminal Emulator | 端末を表示するGUIアプリケーション | Terminal、iTerm2、Konsole |
| TTY | 端末デバイスの抽象インターフェース | /dev/tty1 |
| PTY | ソフトウェアで作られた疑似端末 | /dev/pts/0 |
| Console | システムの主制御用端末を指す、より広い概念 | Linux仮想コンソール |
| CLI | コマンドラインで操作するユーザーインターフェース | Git、npm、PythonのCLI |
日常会話ではTerminal、Console、Shellが混同されます。厳密には、Terminalは入出力の端末、Consoleはシステム制御用の端末という意味合いが強く、Shellはコマンドを解釈するプログラムです。
7. TTY/PTYを必要とするプログラム#
Vim、top、htop、less、nano、ssh、tmuxなどは、単に1行ずつ出力するのではなく、画面全体を操作します。これらは端末の行数と列数、カーソル位置、色、キー入力、Ctrl+Cなどのシグナルを必要とします。
端末がない環境で実行すると、次のようなエラーが出ることがあります。
the input device is not a TTYDockerで対話的なShellを起動するときに-iと-tを付けるのは、この関係のためです。
docker run -it ubuntu bash-i:標準入力を開いたままにする。-t:疑似端末を割り当てる。
8. SSHとtmuxの場合#
SSHでサーバーへログインすると、典型的には次の経路になります。
ローカルのターミナルエミュレーター
↓
ローカルのsshクライアント
↓ ネットワーク
リモートのSSHサーバー
↓
リモートのPTY
↓
リモートのShellサーバー上でttyを実行すると、/dev/pts/3のような結果が表示されることがあります。
tmuxやscreenはターミナルマルチプレクサーです。ターミナルエミュレーターとShellの間に入り、複数のPTYとShellを管理します。これにより、1つのウィンドウで複数のセッションを開いたり、SSH接続が切れた後に処理を再開したりできます。
まとめ#
ターミナルエミュレーター:ユーザーが見るウィンドウ
TTY / PTY :端末入出力を伝えるデバイスインターフェース
Shell :コマンドを解釈して実行するプログラム最も重要な関係は、次の1行です。
ユーザー → ターミナルエミュレーター → TTY/PTY → Shell → プログラム → カーネル
