コマンド入力一撃で端末を大量に分割してタスクを瞬殺するtmux-xpanes

  • 29
    いいね
  • 0
    コメント

この記事の要点

コマンド一撃でtmuxのウィンドウを大量に分割してコマンドの同時実行を助けるxpanes(イクスペインズ)というコマンドを作りました。一斉に複数のホストにpingを送ったり、sshでログインして同時操作したり、一斉に複数のファイルをtail -fしたりするのに使えます。
操作ログの保存機能、標準入力を受け取ってコマンドを作成する機能などなど、機能も充実していて便利です。tmuxを知らない方でも単純な例だけであれば覚えることは少ないので、ぜひお試しを。
下記のアニメを見ていただければ、どんな感じのものを作成したのかお分かりいただけると思います。

tmux-xpanes Animation

logo

Github: https://github.com/greymd/tmux-xpanes

背景

tmuxを使っている方は、どのような用途でtmuxを役立てることが多いでしょうか?開発の効率を上げるため1、あるいは複数のウィンドウ2やペイン3を駆使してサーバのモニタリングをするためなど、人により様々だと思います。

その中でもよく見かけるのが、tmuxでペインを分割し、sshで複数のホストに接続する方です4。かなり多くの方が、tmuxのサブコマンドを並べてスクリプトを組んでいるようです5 6 7 8(そしてなかなか思い通りに分割できずに苦しんでいる方も多かったのではと思います)。

しかし、ssh だけではなく、他のコマンドもウィンドウ分割をして実行することができれば、複数のホストにpingを送ったり、curlを定期的に叩いて簡単な死活監視をしたりすることができるので色々便利になるのではないかと思います。「任意のコマンドを、ウィンドウを分割しつつ複数のペイン上で実行する」という操作を、もっと部品化できないかと考えたのが tmux-xpanes というソフトウェアを作成した経緯です9

tmux-xpanesとは?

今回作成したtmux-xpanesというソフトウェア、すなわちxpanesコマンドは、UNIXのxargsコマンドを叩くような気軽さで、ペイン3を分割できるコマンドです。そのため名前はUNIXのコマンドであるxargsとtmuxのペイン(pane)をかけ合わせたものになっています。

似たようなソフトウェア

tmuxinator

tmuxのセッション情報を管理するソフトウェアです。ウィンドウやペインの配置と分割方法をYAMLファイルに記述すると、そのファイルを読むだけで、特定のtmuxセッションの作成が可能となります。日常的に繰り返し同じようなtmuxの分割スタイルを取る方には大変重宝するソフトなんじゃないかなと思います10
しかし、その場限りの思いつきでウィンドウを分割し、設定ファイルもソースコードも残さずにタスクを瞬殺する、シェル芸11のような思想では使いにくいですし、そういうコンセプトのソフトウェアでは無いです。

tmux-cssh

挙動としてはtmux-xpanesと比較的似たソフトウェアですが、sshでのログインのみに特化しています。コマンドの引数をホスト名として扱い、ウィンドウを複数のペインに分割してsshで接続をします。ホストの集合をファイルで管理してそれを読み込んでログインもできます。ある程度数が多い、特定の組み合わせのホストに頻繁にログインする方には良いかもしれません。

しかしながら、個人的にはまだ不便を感じることが多かったです(これも今回作成したモチベの一つです)。理由としては、コマンドの柔軟さに欠ける点12、個人的に欲しい機能が無い点13、既に動作中のtmuxセッションからは実行できない点などは微妙です14

xpanesの動作環境

下記の2つのソフトウェアを動作要件として定め、動作を確認しています。
tmuxさえ入れば、あとは多くのUNIX環境で動くのではないかと思います15

  • Bash 3.2 以上
  • tmux 1.6 以上

インストール方法

詳しくはGithubのwiki > Installationをご覧ください。いくつかインストール方法をご紹介します。

apt

Ubuntu16向けの方法です。

Terminal
# `add-apt-repository` がない場合はインストール
$ sudo apt install software-properties-common

# PPAリポジトリを追加
$ sudo add-apt-repository ppa:greymd/tmux-xpanes

# インストール
$ sudo apt update
$ sudo apt install tmux-xpanes

Homebrew

macOSをお使いの方はHomebrewが使えます。

Terminal
$ brew tap greymd/tools
$ brew install tmux-xpanes

手動インストール

(この方法をとる方はtmuxを自前で入れる必要があります。)

Terminal
# wgetで落とす
$ wget https://raw.githubusercontent.com/greymd/tmux-xpanes/master/bin/xpanes -O ./xpanes

# パスを通す
$ sudo install -m 0755 ./xpanes /usr/local/bin/xpanes

Zsh ユーザ向け

(この方法をとる方はtmuxを自前で入れる必要があります。)

Zshのプラグインマネージャに対応しています。下記はzplugを使った例です。Zshの補完関数も有効になるのでおすすめです。

terminal
zplug "greymd/tmux-xpanes"

Zsh 補完関数のインストール

Zsh用の補完関数は便利なのでZshをご利用の方はぜひご活用ください。実行可能なオプションや引数の列挙に加え、後述する--sshオプション後に、~/.ssh/configからホスト名を補完してくれる機能などが揃っており、大変オススメです。

プラグインマネージャをご利用の方は、既に述べた方法で補完関数が有効になっています。そうではない方は、Wikiに記載の方法に従ってください。

xpanes コマンド

基本的なインストール方法をとるとxpanestmux-xpanesコマンドの2種類がインストールされますが、どちらも同じコマンドになります17。お好きな方をご利用ください。記事内ではxpanesコマンドを使います。

簡単な動作例

インストールが完了したら、まずお試しに下記のコマンドを実行してみましょう。

Terminal
$ xpanes 1 2 3 4

すると、このような出力が得られるはずです。

Terminal
$ echo 1                       │$ echo 2
1                              │2
                               │
                               │
                               │
                               │
                               │
                               │
-------------------------------+-------------------------------
$ echo 3                       │$ echo 4
3                              │4
                               │
                               │
                               │
                               │
                               │
                               │

デフォルトの動作では与えられた引数をechoコマンドの引数として実行します。実行時には新規にウィンドウが作成され、与えられた引数分ウィンドウが分割されます。

tmuxを使い慣れていない方は、キーバインドがわからないと思います。ここから何をしてよいかわからないかもしれませんが、心配はいりません。exit と打った後にEnterキーを打つと、全てのペインが閉じ、元のスクリーンに戻ります18

Terminal
$ exit                         │$ exit
                               │
                               │
                               │
                               │
                               │
                               │
                               │
-------------------------------+-------------------------------
$ exit                         │$ exit
                               │
                               │
                               │
                               │
                               │
                               │
                               │

このように、デフォルトの状態では、キーを入力すると全てのペインにその入力が反映されます(キー入力の同期を無効にする方法は後述)。

-c オプションと -I オプション

-c オプションを使うことで、echo以外の任意のコマンドを実行することができます。例えば、下記のコマンドを実行してみましょう。

Terminal
$ xpanes -c 'seq {}' 1 2 3 4

すると、このような出力が得られます。

Terminal
$ seq 1                        │$ seq 2
1                              │1
                               │2
                               │
                               │
                               │
                               │
                               │
-------------------------------+-------------------------------
$ seq 3                        │$ seq 4
1                              │1
2                              │2
3                              │3
                               │4
                               │
                               │
                               │

seqコマンドは、連続した番号を出力するコマンドです。それが-c オプションにより指定されました。ご覧の通り {} という箇所がそれぞれの引数に置換されています。この{}という置換される文字列は -I オプションで変更することができます。このような感じです。

Terminal
$ xpanes -I@ -c 'seq @' 1 2 3 4

デフォルトの動作、すなわち-cオプションが指定されないとecho {}がデフォルトのコマンドとなるわけです。

ブレース展開を活用しよう!

BashやZshなどにより提供されるブレース展開を活用すると、連番や連続するアルファベットを生成するのに便利です。xpanes コマンドへの引数に活用してみましょう。

Terminal
# これは $ xpanes 1 2 3 4 と実行したのと同じです
$ xpanes {1..4}

いかがでしょう?ここまでの説明だけでもかなり使えそうな気がしてきたんじゃないでしょうか。

動作仕様

基本的な動作は知っていただいたと思います。これから xpanes コマンドを具体的に役立てるための応用例を見せていきたいと思うのですが、その前に、このコマンドの動作モードについて説明します。xpanes コマンドは、状況によって3種類の異なる動作をするコマンドです。

tmuxセッション外の動作

tmuxを普段使っていない方は、最初にこのモードで使うことになると思います。xpanes コマンドをインストールし、端末を開いてそのままこのコマンドを実行したときxpanesコマンドは新規にtmuxのセッション19とその中にウィンドウを作成します。そのウィンドウをさらにペインに分割して、端末に表示(アタッチ20)します。

tmuxセッション内の動作

常にtmuxを使う方(例えば端末を開いた瞬間にtmuxが最初から開き、基本的にその中で普段の作業をするような方)もいると思います。そのような方の場合、すでに存在するtmuxのセッション内からxpanesコマンドを実行することになると思います。この時xpanesコマンドは既存のtmuxセッションに更に新規ウィンドウを作成し、そのウィンドウを分割して端末にアタッチします。

tmuxセッション内かつ & 標準入力があるとき (Pipeモード)

上記の「tmuxセッション内の動作」に加えて、コマンドが標準入力を受け付ける状態の時。具体的には他のコマンドとパイプ |xpanes コマンドに対して繋がったときは、Pipeモードという動作モードになります。これはUNIXの xargs コマンドと似た動作をするモードです。詳しくは後述します。

応用例

ここからは、私がxpanesコマンドを使ってよくやる応用例を紹介したいと思います。

複数ホストへの同時ping

入力

Terminal
$ xpanes -c "ping {}" 192.168.1.{5..8}

出力

Terminal
$ ping 192.168.1.5             │$ ping 192.168.1.6
                               │
                               │
                               │
                               │
                               │
                               │
                               │
-------------------------------+-------------------------------
$ ping 192.168.1.7             │$ ping 192.168.1.8
                               │
                               │
                               │
                               │
                               │
                               │
                               │

既に述べたブレース展開を使った例です。IPアドレスや連番が含まれているホスト名を列挙するのに大変便利で、xpanesコマンドと相性抜群です。このように結果が一覧して見えるので、死活監視にとても良いです。

複数同時tail

入力(本来1行でOKですが、エスケープ文字\で適宜改行しています)

Terminal
$ xpanes -c "tail -f {}" \
/var/log/apache/{error,access}.log \
/var/log/application/{error,access}.log

出力

Terminal
$ tail -f /var/log/apache/error.log       │$ tail -f /var/log/apache/access.log
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
------------------------------------------+------------------------------------------
$ tail -f /var/log/application/error.log  │$ tail -f /var/log/application/access.log
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │

ログイン先のホストにtmuxが入っていれば、こんな感じに一気に複数のアクセスログを見るのに使えるかもしれませんね。アプリケーションサーバにtmuxが入っていない?ホストが一種類であれば、こんな感じにssh経由で実行すれば良いだけですね。

Terminal
# 'ssh user@host' が追加された。
$ xpanes -c "ssh user@host tail -f {}" \
/var/log/apache/{error,access}.log \
/var/log/application/{error,access}.log

複数ホストへの同時ssh

入力

Terminal
$ xpanes -c "ssh myuser@{}" host1 host2

出力

$ ssh myuser@host1             │ $ ssh myuser@host2
                               │
                               │
                               │
                               │
                               │
                               │

この例ができると嬉しい方が一番多いんじゃないかと思います。この例では、ログインするホスト全てにmyuserというユーザを使っています。ホストごとにユーザを変えたい場合は、こんな感じにすればよいだけですね。

Terminal
$ xpanes -c "ssh {}" myuser1@host1 myuser2@host2

専用オプション

実は、--ssh というssh専用のオプションを用意しています。

Terminal
$ xpanes --ssh myuser1@host1 myuser2@host2

これは、下記のコマンドを実行した場合と同じです21

Terminal
$ xpanes -c "ssh -o StrictHostKeyChecking=no {}" myuser1@host1 myuser2@host2

sshコマンドに-o StrictHostKeyChecking=noというOpenSSHの警告文を無視するオプションをつけて実行します。sshでどこかのホストに初めてログインすると、OpenSSHが発する警告文にyes/noで答えなければいけません。それが面倒な方はこのオプションを使うのも良いでしょう。22

複数ペインへの同時入力を無効にする

キーボードの入力は複数のペイン間で同期しないほうが良い、という状況もあると思います。そんな時は-d (あるいは--desync) オプションを使うと、キーボードを入力しても操作が一つのペインにしか適用されません23。再度同期したい方は、tmuxのsynchronize-paneオプションをonにして下さい。

Terminal
$ xpanes -d -c "ssh myuser@{}" host1 host2

操作ログの保存

--log オプションという、操作ログを保存する機能があります。これは、分割されたペインの出力や、ペインに対するキーボードからの入力を全てペインごとに分割されたファイルに書き出してくれる機能です。

Terminal
$ xpanes --log=~/operation_log -c "ssh myuser@{}" host1 host2

上記の例では--logというオプションに続いてログを保存するディレクトリを指定しています。その後、操作をするとログが保存されます。引数としてhost1host2を渡したのでそれぞれをファイル名に持つファイルができます。

Terminal
$ ls ~/operation_log/
host1-1.log.2017-03-15_21-30-07
host2-1.log.2017-03-15_21-30-07

ログのファイル名のフォーマットは--log-formatオプションで変更することができるのでxpanes --helpで使い方を参照してみて下さい。

なお、このロギング機能に関しては、tmuxのバグで利用できないtmuxのバージョンが存在するのでご注意下さい。Githubのwiki > Known Bugs を参照して下さい。

一発で複数のモニタリング用コマンドを実行

-e オプションを使うと、与えられた引数をそのままコマンドとして実行します。例えば下記の例を実行してみましょう。

Terminal
$ xpanes -e "top" "vmstat 1" "watch -n 1 df"

するとこのような出力が得られます。topでロードとプロセスを確認しつつ、vmstat 1で毎秒CPUとメモリの利用状況を確認しつつwatch -n 1 df で毎秒ストレージの残量を確認します。

$ top                          │$ vmstat 1
                               │
                               │
                               │
                               │
                               │
                               │
-------------------------------┴------------------------------
$ watch -n 1 df






この例は、下記のコマンドを実行した場合と同等です。

Terminal
$ xpanes -c "{}" "top" "vmstat 1" "watch -n 1 df"

分割方法の変更

-l オプションに続き、特定の引数を渡すと、ペインの分割方法を変更することができます。下記の例はペインを上から下に垂直方向に均等に並べるev(tmuxでeven-verticalと呼ばれている分割方法)という命令を適用する例です。

Terminal
$ xpanes -l ev -c "{}" "top" "vmstat 1" "watch -n 1 df"

下記のようにペインが垂直方向均等に並びました24

Terminal
top




-------------------------------------------------------------
vmstat 1




-------------------------------------------------------------
watch -n 1 df




同様に、水平方向に均等に並べるeh (tmuxではeven-horizontalと呼ばれる)や最初のウィンドウを大きめにして、残りは垂直あるいは水平に均等に並べるmv(main-vertical)、mh(main-horizontal)もあります。覚えられない場合はxpanes --helpで使い方を参照して下さい。

複数ユーザでの画面共有

xpanesコマンドを使うと~/.cache/xpanes/socket というファイルが自動的に作成されます。これはtmuxのソケットファイルと呼ばれ、セッションの情報を持っています。このファイルを利用することで、複数のユーザ間でtmuxを使って画面(セッション)共有が可能です。

このソケットファイルはtmuxと同様に-Sオプションを使うことで、任意のパスに作成することができます。

user1がxpanesとソケットを作成

Terminal(user1)
[user1@host] $ xpanes -S /home/user1/mysocket a b c d ...

user2がtmuxでソケットファイルを読み込む

Terminal(user2)
[user2@host] $ tmux -S /home/user1/mysocket attach

上記のようにすることで、user1とuser2の両者でリアルタイムな画面共有ができます。

複数ウィンドウを作成しつつペイン分割

xpanesの「tmuxセッション内で実行されると新規ウィンドウが作成される」という性質を利用して、複数ウィンドウの作成を比較的手軽にすることができます。xpanesを使ってxpanes自身を呼び出す、ちょっとトリッキーな方法です。

下記のコマンドを実行してみましょう。

Terminal
$ xpanes -c "xpanes -I@ -c 'ssh @' {} && exit" \
  "groupA-host1 groupA-host2" \
  "groupB-host1 groupB-host2 groupB-host3" \
  "groupC-host1 groupC-host2"

すると、下記のような組み合わせで、新規ウィンドウが3つ作成されます。

ペイン1 ペイン2 ペイン3
ウィンドウ1 ssh groupA-host1 ssh groupA-host2 ※なし
ウィンドウ2 ssh groupB-host1 ssh groupB-host2 ssh groupB-host3
ウィンドウ3 ssh groupC-host1 ssh groupC-host2 ※なし

なぜこのような動作になるのか、順を追って説明します。

Terminal
$ xpanes -c "xpanes -I@ -c 'ssh @' {} && exit" \
  "groupA-host1 groupA-host2" \
  "groupB-host1 groupB-host2 groupB-host3" \
  "groupC-host1 groupC-host2"

このコマンドを実行すると、まず最初に下記の結果が得られます。

$ xpanes -I@ 'ssh @' groupA-host1 groupA-host2 && exit │$ xpanes -I@ 'ssh @' groupB-host1 groupB-host2 groupB-host3 && exit
                                                       │
                                                       │
                                                       │
                                                       │
                                                       │
                                                       │
-------------------------------------------------------+-------------------------------------------------------
$ xpanes -I@ 'ssh @' groupC-host1 groupC-host2 && exit






まず、一番左上のペインに注目してみましょう。

Terminal
$ xpanes -I@ 'ssh @' groupA-host1 groupA-host2 && exit

このコマンドがtmuxセッション内で実行されると、新規にウィンドウを作成し、下記のようなコマンドを実行します。

$ ssh groupA-host1             │ $ ssh groupA-host2
                               │
                               │
                               │
                               │
                               │
                               │

xpanesコマンドと併記して&& exitというコマンドがが指定されています。これにより新規にウィンドウを作成した後にxpanesコマンドが実行されたペイン自身は閉じるという挙動をするようになります。すなわち、新規に2分割されたウィンドウを作成した後、左上のペインは自動的に閉じることになります。

この挙動が同様に、右上、そして下のペインでも実行されます。xpanesコマンドを3つ実行した先ほどのウィンドウは、3つの新規ウィンドウを作成したのちに、保有するペインをなくして自滅します。結果的に、任意の個数のウィンドウを開きつつ、任意のペイン分割でコマンドを実行させることができます。

日常的に決まったウィンドウ分割方法をするのであれば、ウィンドウの名称やペインサイズも細かく設定できるtmuxinatorを使ったほうが良いと思いますが、一回きりの使い捨てであれば、上記のようなコマンドで十分でしょう。先述した動作モードの動きを理解して慣れてしまえば、スムーズに上記のようなコマンドが記述できます。

Pipeモード

パイプで標準入力を受け取っている場合、xpanesコマンドはPipeモードという動作モードになります25。これはtmuxセッション内のみの動作になります26。UNIXのコマンドであるxargsを強く意識したコマンドです。

tmux_session
# Pipe モード
$ seq 3 | xpanes

上記のコマンドを実行すると、この様な出力が得られます。

$ echo 1                                  │$ echo 2
1                                         │2
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
------------------------------------------+------------------------------------------
$ echo 3
3                                          








Pipeモードは、下記の2つの点で、通常のモードとは異なる挙動をします。

  1. 標準入力から受け取った1行が、通常モードでいう1引数のような扱いをされるようになる。
  2. コマンドに対する 引数が実行されるコマンドの一部になる (通常のモードの-cオプションに相当、デフォルトはecho {})。

違う例をお見せしましょう。

tmux_session
# こんな挙動をするコマンド
$ seq 4
1
2
3
4

# これをxpanesに標準入力で与える
$ seq 4 | xpanes printf

結果はこうなります。

$ printf 2                                │$ printf 4
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
------------------------------------------+------------------------------------------
$ printf 6                                │$ printf 8
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │

もちろん、-cオプションも-Iオプションも使えます。

tmux_session
$ seq 4 | xpanes -c 'printf {}'
##  xpanes printf と xpanes -c 'printf {}' は同じ

ただしその場合、引数も両方同時に与えると、コマンドがどちらを使ってよいのかわからないので、エラーになってしまいます。

tmux_session
$ echo test | xpanes -c 'echo {}' echo
# Error: Both arguments and '-c' option are given.
# => エラーになる

xpanes コマンドで実行するコマンドにパイプを含めたいときは-cオプションを使ったほうが良いと思います。

Terminal
# => うまくいかない
$ echo hello | xpanes echo | grep hello
Terminal
# => うまくいく
$ echo hello | xpanes -c 'echo {} | grep hello'

ホスト一覧表から一斉にsshする

Pipeモードの利点は、何かのファイルをパースした結果を、特別なことをせずに、そのままxpanesの標準入力に与えることができる点です。たとえば、こんな感じの~/.ssh/configファイルが存在したとします。

~/.ssh/config
Host host1
    User user1
    HostName 192.168.0.2
    IdentityFile ~/.ssh/id_rsa

Host host2
    User user2
    HostName 192.168.0.3
    IdentityFile ~/.ssh/id_rsa

Host host3
    User user3
    HostName 192.168.0.4
    IdentityFile ~/.ssh/id_rsa

まずここからHostを抜き出してみましょう。シェル芸に慣れた人であれば簡単ですね27

Terminal
$ cat ~/.ssh/config | awk '$1=="Host"{print $2}'
host1
host2
host3

そして、それをxpanesコマンドに渡してsshでログインしましょう。

Terminal
$ cat ~/.ssh/config | awk '$1=="Host"{print $2}' | xpanes ssh

こんな出力が得られるはずです。

$ ssh host1                               │$ ssh host2 
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
------------------------------------------+------------------------------------------
$ ssh host3









最初のアニメーションで紹介したように、50台くらいのホストであっても安定してウィンドウを分割してくれます28

コマンド一覧表からコマンドを並列実行する

使い方に慣れないうちは一旦ファイルにコマンドを記述して、それを標準入力として与えると良いかもしれませんね。

Terminal
# command-listという、コマンドを記述したファイルを用意
$ cat command-list
top
vmstat 1
watch -n 1 df
while true; do curl -I localhost:8080 && sleep 1 ;done

# -e オプションでそのまま実行
$ cat command-list | xpanes -e

出力

Terminal
$ top                                     │$ vmstat 1
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
------------------------------------------+------------------------------------------
$ watch -n 1 df                           │$ while true; do curl -I localhost:8080 && sleep 1 ;done
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │
                                          │

プリキュア49人全員の変身口上

プリキュア29関連の情報を扱うCureutilsというコマンドラインツールにcure echoというコマンドがあります。このコマンドを使うことで、プリキュアが変身する時の口上を表示することができます。普通の端末では、せいぜい同時に表示できても数人ですが、xpanesを使うことで、プリキュア全員30の変身の口上を一覧して確認することができます。大変便利ですね。

Terminal
$ cure precures \
| cure tr '[:precure_name:]' '[:girl_name:]' \
| xpanes -c 'cure echo -p {}'

Screen Shot 2017-05-08 at 10.31.30 PM.png

cure precuresでプリキュアの一覧を表示
cure trで名前を英名に変換
xpanesを使ってcure echoコマンドに噛ませる

2017/05/07現在、テレビに出演したメインヒロインは49人なので、7x7の平方数になり、綺麗に分割できます。

オウムを並べて Choo Choo TRAINさせる

ここまで真面目な活用例をお見せしてきましたが、ちょっとした遊び用途で使っても楽しいと思います。例えばterminal-parrotという、楽しげな動きをするオウムを端末に表示するスクリプトを使ってみましょう。

Terminal
$ yes terminal-parrot | head -n 25 | xpnaes -e 

parrot_movie.gif

SLをたくさん走らせる

sl コマンドを使ってみましょう。

Terminal
$ yes 'sl -l' | head | xpanes -elev

sl_movie.gif

むすび

「その場限りの使い捨てのコマンドでペインを分割する」というコンセプトをもったtmux-xpanesならびにxpanesコマンドの紹介をしました。

既存の分割支援ソフトにはない汎用性と機能とコンセプトを持っているので「こんなソフトウェアを待っていた!」という方がいたら喜ばしい限りです。このコマンドの面白い使い方があれば是非教えてください。

また、ソースはGithubで公開しているので、Wikiの編集、バグの報告や、機能追加の提案、プルリクエストなどもお待ちしています。


  1. 私は開発中に、エディタを開きつつ端末からコマンドを走らせるためにtmuxを活用しています。 

  2. この記事では「ウィンドウ」と「ペイン」という言葉を使います。両方とも、tmuxで使われる用語として使いますので、GUIのウィンドウとは異なるものです。定義はこちらによくまとまっていました。 

  3. ペインとは「ウィンドウを分割した領域」のことです。参考 

  4. 例えばこのような方です http://qiita.com/catatsuy/items/3aa7bd49399bba66d8f1 

  5. tmux-csshで複数サーバに対するカジュアルなオペレーション 

  6. tmuxで複数にsshしてコマンドシンクするスクリプト by @mikeda 

  7. Start multiple synchronized SSH connections with Tmux 

  8. tmuxで複数サーバの同時オペレーション 

  9. tmux-xpanesソフトウェア名の総称で、xpanesはコマンド名として記事内では使います。 

  10. 例えば、開発時のエディタとターミナルの分割方法が常に特定のパターンでないと落ち着かない人とかです。 

  11. マウスも使わず、ソースコードも残さず、GUIツールを立ち上げる間もなく、あらゆる調査・計算・テキスト処理をCLI端末へのコマンド入力一撃で終わらすこと。あるいはそのときのコマンド入力のこと。 from シェル芸の定義バージョン1.1 

  12. sshのみに特化しているが故に、柔軟な操作ができないことです。例えば、特定のホストには-iオプションで特定の秘密鍵を使いたい、初回ログイン時のyes/noの質問を避けるためにStrictHostKeyChecking=noしてログインしたい、などということができません。 

  13. xpanesは、汎用的なコマンドの実行をサポートしているのに加え、後述するロギング機能や標準入力を受け取って処理する機能もあります。xpanesはその場限りの使い捨てのコマンドを実行しやすくするというコンセプトを持たせており、ちょっとtmux-csshとは違うコンセプトのソフトウェアですね。ちなみにxpanesには--sshオプションと、~/ssh/configを自動的に取得して補完に利用するZshの補完関数が存在します。そのため私が個人的に使う限りは接続するホスト名の列挙にはあまり困ったことはないです。sshでログインするホストは、名前に専用のprefixをつける、複数の名前を持たせるなど工夫して全て~/ssh/configに記述してしまえば良いと私は考えています。 

  14. 一応Issueとしては上がっているようで、PRもあるようなのですが、メンテされてないようで、取り込まれてないです。。 https://github.com/dennishafemann/tmux-cssh/issues/30 xpanesは、動作モードを別にすることで、既存のtmuxセッション内からの実行が可能です。 

  15. 正直なところかなり古い環境を動作要件として設定しています。本当はtmux 1.8以上とbash 4.0以上くらいにしたかったんですが、私が個人的に使いたい環境が古かったので、こうしてます。 

  16. インストールが可能なUbuntuのバージョンはtmux-xpanesのWikiを参照してください。Preciseは最近サポートが切れたので用意していません。マニュアルでインストールしてください。 

  17. tmux-cssh のようにtmux関連のコマンドにはtmux-というprefixをつけておいたほうがtmux-と打ってtabキーを押すだけでコマンド名が候補として現れるので、「tmux関連のコマンドなんかあったよな」と漠然と思っている人にも使ってもらえるかな、という配慮です。 

  18. 開いているのはtmuxのペインなので、もちろんtmuxのキーバインドを使って閉じても良いです。 

  19. tmuxの用語にsession(セッション)という言葉があります。「ウィンドウの集まりを総称したもの」です。参考 

  20. tmuxの用語にattach(アタッチ)という言葉があります。これは「作成したセッションを、実際にユーザが見える形で画面に表示する」くらいの意味で捉えていただいて構いません。ちなみにtmuxのセッションはアタッチされていなくても、裏で起動させることができます。その状態にすることをデタッチとも呼びます。 

  21. これも完全に自分の好みで作りました。 

  22. 普段から大量のホストにログインする方は、何らかの理由でフィンガープリントが変わって警告文が出現することがよくあると思います。そのような時にあくまで接続先が明確に信頼できる確証が持てる場合に一々回答するのが面倒な方はこれを使うと良いと思います。 

  23. これはtmuxのsynchronize-paneオプションをoffにしています。デフォルトではonにします。 

  24. 余談ですが、ペインを分割する線は、水平に伸びているので、最初この状態が水平(horizontal)かと勘違いしていました。ややこしいと思うのは私だけでしょうか? 

  25. 一つのコマンドが、標準入力が存在するときとしないときで大きく動作を変えるのは、UNIX哲学の観点からはあまり良い設計思想ではないかもしれません。しかし私はこのコマンドをどうしてもxargsっぽくも使いたかったのです。シェル芸が捗るからです。叱らないでください。 

  26. tmuxセッション外でも一応Pipeモードは起動できますが、手動のtmuxセッションのアタッチが警告文により促されます。tmux仕様なのか、UNIXの仕様なのかわからないのですが、パイプでつながってforkされた子プロセスからでは、親プロセスのttyが見えず、端末の表示ができないようです。 

  27. そうじゃない人はごめんなさい。 

  28. ちなみに私はこのような方法と高解像度のディスプレイを使って100台以上のホストに同時ログインしたことがあります。 

  29. 日本が世界に誇る国民的アニメ。2017年5月現在「キラキラ☆プリキュアアラモード!」キラッと放送中! 

  30. TVシリーズに出演したことのあるメインヒロイン全員の数です。なのでキュアエコーは含めません。ごめんなさい。メインヒロインではないので満や薫やキュアゴリラやキュアモフルンは含めません。あしからず。