GNU Screenとtmuxのコマンド比較

# はじめに

端末作業には長年 GNU Screen を使っていてそれで事足りていますが、最近はターミナルマルチプレクサというと tmux のことを指すようですので、基本的な操作方法くらいは知っておいた方が良いかなと思い始めた GNU Screen 使いのメモ書きです。思いついた時々で更新します。

# コマンド比較表

## 表記について

*   `C-a` は `Ctrl` を押しながら `a` を押すことを意味します
*   `M-v` は多くの場合 `ESC` を押したあとに `v` を押すことを意味します。`ESC` は `C-[` でも代用できます。
*   キーマップに割り当てられているコマンドについては括弧書きで併記します

## バージョンについて

OS X の homebrew でインストールしたもので確認しています。

* GNU Screen: 4.3.1
* tmux: 2.1

## 用語

|GNU Screen|tmux|
|----------|----|
|ウィンドウ(window) |ペイン(pane) |
|レイアウト(layout) |ウィンドウ(window)|
|セッション         |セッション|


### ウィンドウとペイン

tmux をはじめて使用したときにウィンドウとペインという用語に戸惑いました。

端末(tty)を操作する単位は GNU Screen ではウィンドウ、tmux ではペインと呼び、ペインは最低ひとつのウィンドウと結びつけられます。

### レイアウトとウィンドウ

ペインが一つも無いウィンドウは存在しませんが、似たような概念である GNU Screen のレイアウトはウィンドウと結びついていません。

GNU Screen のレイアウトはバージョン 4.1 から導入されました。これは tmux のウィンドウと同じように表示領域を分割した状態を管理するものですが、端末とは結びつけられず名前の通り分割状態の配置を保存したものです。同じ端末を複数のレイアウトに配置できますし、表示領域に存在しない非表示な端末もあります。

|セッション       |表示領域   |端末              |
|-----------------|-----------|------------------|
|screen セッション|レイアウト0|ウィンドウ0<br>ウィンドウ1|
|                 |           |ウィンドウ2|
|                 |レイアウト1|ウィンドウ0<br>ウィンドウ3|
|tmux セッション  |ウィンドウ0|ペイン0<br>ペイン1|
|                 |ウィンドウ1|ペイン2|
|                 |ウィンドウ2|ペイン3|

GNU Screen のレイアウト機能については以前まとめたものがありますので詳しくはそちらで。

*   [これからの「GNU Screen」の話をしよう](http://yskwkzhr.blogspot.jp/2011/01/gnu-screen.html#layout)
*   [開発版GNU Screenのlayoutを使ってみよう](http://yskwkzhr.blogspot.jp/2011/12/guide-to-using-gnu-screen-layouts.html)


この文書ではウィンドウという用語は基本的に tmux のものを指します。


## コマンドや表示

|操作|GNU Screen|tmux|
|----|----------|----|
|コマンドキーを送信 *1           |`C-a` `a` (`meta`)|`C-b` `C-b` (`send-prefix`)|
|コマンドモード                  |`C-a` `:` (`command`)|`C-b` `:` (`command-prompt`)|
|キーバインド一覧を表示          |`C-a` `?` (`help`)|`C-b` `?` (`list-keys`)|
|画面を再描画                    |`C-a` `l`<br>`C-a` `C-l` (`redisplay`) |`C-b` `r` (`refresh-client`)|
|時刻を表示 *2                   |`C-a` `t`<br>`C-a` `C-t` (`time`)|`C-b` `t` (`clock-mode`)|
|直前に表示されたメッセージを表示|`C-a` `m`<br>`C-a` `C-m` (`lastmsg`) |`C-b` `~` (`show-message`)|
|情報を表示                      |`C-a` `i`<br>`C-a` `C-i` (`info`)|`C-b` `i` (`display-message`)|

1. 設定で変更している場合はそのキーになる。
1. GNU Screen は端末最下行に年月日とロードアベレージも表示、tmux はカレントペインの中央に時刻が大きく表示。

## セッション

tmux はクライアント・サーバ形式を意識した構造となっているため別セッションへ切り替えるコマンドが豊富です。

|操作|GNU Screen|tmux|
|----|----------|----|
|セッションの一覧を表示               |`screen -ls` |`tmux list-sessions`|
|セッションに接続 *1                  |`screen -r` |`tmux attach-session`|
|セッションを切断                     |`C-a` `d`<br>`C-a` `C-d` (`detach`)|`C-b` `d` (`detach-client`)|
|セッションをサスペンド               |`C-a` `z`<br>`C-a` `C-z` (`suspend`) |`C-b` `C-z` (`suspend-client`)|
|セッションの名前を変更               |(`sessionname [ name ]`) |`C-b` `$` (`rename-session`) |
|セッションの一覧から接続             ||`C-b` `s` (`choose-tree`)|
|次のセッションに接続                 ||`C-b` `(` (`switch-client -p`)|
|前のセッションに接続                 ||`C-b` `)` (`switch-client -n`)|
|直前のセッションに接続               ||`C-b` `L` (`switch-client -l`)|
|クライアントの一覧を表示             |`C-a` `*` (`displays`)|(`list-clients`)|
|クライアントの一覧から切断 *2        |`C-a` `*` (`displays`)|`C-b` `D` (`choose-client`)|

1. クライアントが接続していないセッションがひとつの場合。複数存在する場合などは引数でセッションを指定する。
  * GNU Screen: `screen [-x] [-d] -r [[pid.]tty[.host]]`
  * tmux: `tmux attach-client [-d] [-t target-session]`
1. GNU Screen は `displays` の一覧から選択して `d`(detach) または `D`(power detach) で他のクライアントを切断できるが現在使用中のクライアントは切断できない。

## 領域／ペイン

|操作|GNU Screen|tmux|
|----|----------|----|
|上下に分割 *1                     |`C-a` `S` (`split`) | `C-b` `"` (`split-window`) |
|左右に分割 *1                     |`C-a` <code>&#124;</code> (`split -v`) | `C-b` `%` (`split-window -h`) |
|次の領域に移動                    |`C-a` `TAB` (`next`)|`C-b` `o` (`select-pane`)|
|一覧を表示                        |`C-a` `w` (`windows`)|(`list-panes`)|
|現在の領域を削除                  |`C-a` `X` (`remove`)||
|現在の領域だけを表示 *2           |`C-a` `Q` (`only`)|`C-b` `z` (`resize-pane -Z`)|
|現在のウィンドウ／ペインを削除    |`C-a` `k`<br>`C-a` `C-k` (`kill`)|`C-b` `x` (`kill-pane`)|
|直前のアクティブなペインに移動    ||`C-b` `;` (`last-pane`)|
|現在のペインを前のペインと入れ替え||`C-b` `{` (`swap-pane -U`)|
|現在のペインを次のペインと入れ替え||`C-b` `}` (`swap-pane -D`)|
|ペインの配置を変更（時計回り)     ||`C-b` `C-o` (`rotate-window`)|
|ペインの配置を変更（反時計回り)   ||`C-b` `M-o` (`rotate-window -D`)|
|ウィンドウ中のペインの番号を表示  ||`C-b` `q` (`display-panes`)|
|ペインをマーク *3                 ||`C-b` `m` (`select-pane -m`)|
|ペインのマークをクリア            ||`C-b` `M` (`select-pane -M`)|
|現在のペインを別ウィンドウに移動  ||`C-b` `!` (`break-pane`)|
|ウィンドウにペインを追加          ||(`join-pane`)|
|ペインを移動                      ||(`move-pane`)|

1.  tmux は分割と同時にペインが作成される。GNU Screen は分割してできた新たな領域に表示する端末は別途指定する必要がある。
1.  GNU Screen は分割状態をすべて解除してしまうが、tmux は領域の最大化(zoomed)と元に戻す(unzoom)ことを繰り返し実行できる。
1.  マークしたペインは `join-pane` `swap-pane` `swap-window` をする際のデフォルトターゲットとなる

## レイアウト／ウィンドウ

|操作|GNU Screen|tmux|
|----|----------|----|
|作成| (`layout new`)|`C-b` `c` (`new-window`) |
|削除| (<code>layout remove [ n &#124; title]</code>)|`C-b` `&` (`kill-window`)|
|一覧を表示|(`layout show`)|(`list-windows`)|
|番号を変更  |(`layout number [ n ]`) |`C-b` `.` (`move-window -t '%%'`)|
|名前を変更|(`layout title [ title ]`)|`C-b` `,` (`rename-window -t '%%'`)|
|番号または名前を指定して切り替え|(<code>layout select [ n &#124; title ]</code>|`C-b` `'` (`select-window -t ':%%'`) |
|次に切り替え|(`layout next`)|`C-b` `n` (`next-window`)|
|前に切り替え|(`layout prev`)|`C-b` `p` (`previous-window`)|
|直前に選択していたものに切り替え||`C-b` `l` (`last-window`)|
|番号を指定して切り替え    | |`C-b` `0` (`select-window -t :=0`)<br>...<br>`C-b` `9` (`select-window -t :=9`)|
|一覧から選択して切り替え | |`C-b` `w` (`choose-window`)|
|検索して切り替え||`C-b` `f` (`find-window '%%'`)|
|事前定義済みの設定に切り替え| |`C-b` `ESC-1` (`select-layout even-horizontal`)<br>`C-b` `ESC-2` (`select-layout even-vertical`)<br>`C-b` `ESC-3` (`select-layout main-horizontal`)<br>`C-b` `ESC-4` (`select-layout main-vertical`)<br>`C-b` `ESC-5` (`select-layout tiled`)|
|次の事前定義済みの設定に切り替え| |`C-b` `SPACE` (`next-layout`)|

## コピー・ペースト

tmux はコピーモードで選択したテキストなどを格納するバッファに対する操作が豊富です。

GNU Screen では格納先はひとつのバッファ（レジスタ「`.`」）しかなく、複数のテキストを扱いたい場合は別のレジスタに保存する必要があります。また tmux の `list-buffers` のように格納されている文字列を確認する方法は提供されていません。

|操作|GNU Screen|tmux|
|----|----------|----|
|コピーモードに切り替え    |`C-a` `[`<br>`C-a` `C-[`<br>`C-a` `ESC` (`copy`)|`C-b` `[` (`copy-mode`)|
|バッファを貼り付け        |`C-a` `]`<br>`C-a` `C-]` (`paste`)|`C-b` `]` (`paste-buffer`)|
|バッファの一覧を表示      | |`C-b` `#` (`list-buffers`)|
|最近追加したバッファを削除| |`C-b` `-` (`delete-buffer`)|
|一覧からバッファを選択    | |`C-b` `=` (`choose-buffers`)|
|（表示されている領域を）<br>ハードコピー *1                   |`C-a` `h` (`hardcopy`)|(`capture-pane`)|

1.  tmux はデフォルトでは新規バッファに保存。GNU Screen はファイル(`hardcopy.n`)に保存。設定により OS のクリップボードに保存可能。[screenのペーストバッファを自動でOSXのクリップボードに送る方法](http://yskwkzhr.blogspot.jp/2009/08/screenosx.html)

### コピーモード

コピーモードでは vi や emacs のキー操作が行えます。GNU Screen は両方の基本的なキーが使えます。tmux はさらに多くのキーが使用できるため `mode-keys` でどちらのモードか指定する必要があります。モードの設定には `VISUAL` や `EDITOR` 環境変数も参照され、デフォルトは `emacs`。

|コピーモードでの操作|GNU Screen|tmux|
|----|----------|----|
|コピー開始位置指定    |`SPACE`<br>`ENTER`|`SPACE` (vi)<br>`C-SPACE` (emacs)|
|コピー終了位置指定 *1 |`SPACE`<br>`ENTER`|`ENTER` (vi)<br>`M-w` (emacs)|
|コピーモードを終了 *2 |`ESC` |`q` (vi, emacs)<br>`ESC` (emacs)|
|末尾に向けて順方向検索|`/` `[word]`<br>`C-s` `[word]` |`/` `[word]` (vi)<br>`C-s` `[word]` (emacs)|
|先頭に向けて逆方向検索|`?` `[word]`<br>`C-r` `[word]` |`?` `[word]` (vi)<br>`C-r` `[word]` (emacs)|

1.  コピー終了位置指定とともにコピーモードは終了する。
1.  GNU Screen はコピーモードで使用できないキーであれば何でも可。`q` を使うのが無難かも。

# 参考資料

* [screen(1)](http://man7.org/linux/man-pages/man1/screen.1.html)
* [tmux(1)](http://man.openbsd.org/OpenBSD-current/man1/tmux.1)