メインコンテンツへスキップ
  1. ノート/
  2. Linux/

shell・terminal・TTYの違い

·2666 文字·6 分· loading · loading · · ·
ICE345
著者
ICE345
CS Student | System | Linux | OCaml

Shell、Terminal、TTY、PTYは、いずれもコマンドライン操作に関係しますが、同じものではありません。全体を一言で表すと、次のようになります。

ユーザー
  ↓ キーボード入力
ターミナルエミュレーター
  ↓ 端末デバイスを提供
TTY / PTY
  ↓ 入出力を伝える
Shell
  ↓ コマンドを解釈してプログラムを起動
カーネル / アプリケーション

1. Shellとは何か
#

Shellは、ユーザーが入力したコマンドを解釈し、プログラムを起動するコマンドインタープリターです。

ls -l
cd Desktop
python main.py

代表的なShellには、次のものがあります。

Shell特徴
shUnixで広く使われた基本的なShell
bashLinuxで非常によく使われるShell
zshmacOSの標準Shellとしても使われる
fish対話操作を重視した現代的なShell
PowerShellWindowsで広く使われるShell

Shellは、コマンドの実行だけでなく、変数、パイプ、リダイレクト、ワイルドカード展開、スクリプトも処理します。

cat a.txt | grep hello > result.txt

この例の|>は、catgrepが解釈するものではなく、Shellがコマンドを実行する前に処理します。

bashzshfishは文法、組み込みコマンド、補完、対話的な使い勝手が異なります。しかし、いずれも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

処理の流れは次のとおりです。

  1. Terminal.appがウィンドウを開く。
  2. Terminal.appがPTYを作成する。
  3. Terminal.appがzshを起動する。
  4. ユーザーがecho helloを入力する。
  5. zshがコマンドを解析する。
  6. zshechoを実行する。
  7. echohelloを出力する。
  8. 出力がPTYを通ってTerminal.appへ戻る。
  9. Terminal.appがウィンドウへhelloを表示する。

6. 用語を比較する
#

用語本質
Shellコマンドを解釈して実行するプログラムbashzshfish
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 TTY

Dockerで対話的なShellを起動するときに-i-tを付けるのは、この関係のためです。

docker run -it ubuntu bash
  • -i:標準入力を開いたままにする。
  • -t:疑似端末を割り当てる。

8. SSHとtmuxの場合
#

SSHでサーバーへログインすると、典型的には次の経路になります。

ローカルのターミナルエミュレーター
ローカルのsshクライアント
        ↓ ネットワーク
リモートのSSHサーバー
リモートのPTY
リモートのShell

サーバー上でttyを実行すると、/dev/pts/3のような結果が表示されることがあります。

tmuxscreenはターミナルマルチプレクサーです。ターミナルエミュレーターとShellの間に入り、複数のPTYとShellを管理します。これにより、1つのウィンドウで複数のセッションを開いたり、SSH接続が切れた後に処理を再開したりできます。

まとめ
#

ターミナルエミュレーター:ユーザーが見るウィンドウ
TTY / PTY              :端末入出力を伝えるデバイスインターフェース
Shell                  :コマンドを解釈して実行するプログラム

最も重要な関係は、次の1行です。

ユーザー → ターミナルエミュレーター → TTY/PTY → Shell → プログラム → カーネル

评论