こんにちは。株式会社フィックスポイントのよしだです。
今回は、 echo
コマンドの応用編として、エンジニアの tennashiさんより、クリップボードへの書き込み・読み込みについて発表がありました。
前回に比べて、少し踏み込んだ内容になっていますので、 echo
コマンドを活用したい方は、是非読んでみてください。(前回の記事はこちら)
クリップボードにコピーする
実行するコマンドは以下の通りです。
$ echo -e "\e]52;c;ZnVnYWZ1Z2E=\a"
ここでは、単一のスケープシーケンスを実行しているため、 echo
コマンド自体の実行結果は空(行)になっています。*1
今回も、前回同様にコマンドを分割して考えてみましょう。
すると、以下のように分けることが可能です。
-
\e]*\a
: カテゴリ指定52
: コマンドの種類c
: パラメータその1ZnVnYWZ1Z2E=
: パラメータその2
それぞれの要素を見ていきましょう。
カテゴリ指定
カテゴリ指定については、少しだけ文字が変わっていることに注目してください。
文字色の変更のときは \e[
から始まっていましたが、今回は \e]
から始まっています。
\e]
から始まるエスケープシーケンスは、 OS に関連した操作が定義されています。
その中に、今回利用しているクリップボード連携機能もあります。*2
終端文字も変更されており、今回は m
ではなく \a
に変わっています。
\a
は、本来であればベル文字と呼ばれており、(そのように設定している PC では)単体で使えば PC からビープ音が鳴るようになっています。
ただ今回は、一連のシーケンス終端文字として解釈されるので、実行の度にビープ音が鳴ったりはしません。*3
コマンドの種類
この項目については、特に変わったことはありません。
52
がクリップボード連携コマンドを意味しています。
パラメータの種類
先にパラメータその2の ZnVnYWZ1Z2E=
に着目しましょう。
お分かりの方もいるかと思いますが、Base64 エンコードされた fugafuga
です。
echo
コマンドでは、次のように生成が可能です。
$ echo -en "fugafuga" | base64
ZnVnYWZ1Z2E=
Base64とは?
a-zA-Z0-9+/
の64 文字で表現するための仕様です。
例えば、 HTTP 1.1 では送受信されるデータはテキストデータと定められています。
そのため、HTTP の範囲内で画像(バイナリデータ)等を送受信する際は、何らかの方法でテキストデータ(つまり "目" で認識できる文字列) に変換する必要があります。
Base64 は、このような場合に有用です。
ちなみに、=
はデータ長を調整するためのパディングにのみ使われます。
そのことから、先の文字列を見て Base64 エンコードされていることが、分かる人には分かるという訳です。(もちろんそうでない場合も多々あります)
今回のエスケープシーケンスでは、クリップボードに挿入したい文字列を Base64 に変換したものをパラメータに指定することになっています。
そのため、 ZnVnYWZ1Z2E=
を指定しているのです。
次に、先程飛ばしたパラメータ1の c
について説明します。
これは、いわゆる Ctrl+C
Ctrl+V
で操作できるクリップボードを使うことを意味しています。
コマンドの種類を 52
とした時点で、クリップボード連携というのは分かっているのに、さらにクリップボードを指定するとは…?と思われた方もいるかもしれません。
実は、Linux における標準的なデスクトップ環境 X11 では、クリップボードと言ったときには複数のバッファが存在しています。
それらは CLIPBOARD
PRIMARY
SECONDARY
と呼ばれており、どれを利用するのかは明示しなければなりません。
CLIPBOARD
バッファがいわゆるクリップボードとなっており、それを利用するという指定が c
となっているのです。
まとめ
以上の内容から、最初に示したエスケープシーケンスの意味はご理解いただけたのではないでしょうか。
クリップボードの読み込み
冒頭でもお伝えした通り、クリップボードへは書き込みだけでなく読み込みも可能です。
入力するエスケープシーケンスは以下の通りです。
$ echo -e "\e]52;c;?\a"
これを実行すると、現在 CLIPBOARD
に入っている文字列が ?
の部分に補完された状態で表示されます。
先程の書き込みの際と同じく、 Base64 エンコードされた状態のものにはなりますが、読み込みが可能という訳です。
クリップボード読み込みの危険性
クリップボードの読み込み手順をご紹介はしましたが、この機能はある意味で危険です。
クリップボードには、比較的センシティブな情報が入っていることもあるため、それが手軽に取得できるのは危険だと言えます。
例えば、 curl | sh
によるインストール手順に、クリップボードの内容を取得して外部に投げるという操作が書かれており、情報漏洩に繋がる可能性もあるのです。
そのような危険性があるため、クリップボードの読み込み機能をデフォルトで無効にしているターミナルエミュレータや、そもそも実装していないものも存在しています。
具体的には、iTerm2 は前者で、gnome-terminal(VTE 系) は後者です。
ちなみに、今回の勉強会担当者が利用している Alacritty はデフォ有効でした。
おまけ: tmux とクリップボード
今までの話題に関連して、tmuxとクリップボードの関係について記載しておきます。
tmux.conf を開くと、以下のように記述してあるのではないでしょうか。
bind-key -T copy-mode-vi C-j send -X copy-pipe-and-cancel 'xsel -i'
bind-key -T copy-mode-vi Enter send -X copy-pipe-and-cancel 'xsel -i'
bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel 'xsel -i'
これは、 tmux でクリップボード連携をするための設定としてよく紹介されているものです。
まず、この設定値が機能していない可能性があることを念頭に置いてください。
tmux には set-clipboard
オプションが存在し、前項までで説明したエスケープシーケンスによるクリップボード連携機能の有効無効を設定できるようになっています。
ちなみに、tmux 2.6 以降ではデフォルトで有効化されています。
先に記述した bind-key
による設定はエスケープシーケンスではなく、 xsel
コマンドを利用した別のクリップボード連携方法です。
このことから、両設定が実のところコンフリクトしている可能性があるのです。
そのため、bind-key
による設定を正しく使いたければ、 set-clipboard
オプションを off
にしておくとよいです。
さらに、 tmux 3.2 からは copy-command
というオプションが追加されており、上記 bind-key
による設定を消し、以下のコマンドを入力することで同じ挙動にできます。
set-option -s copy-command 'xsel -i`
set-clipboard
のデフォルト値で動くならそれでよいと思われるかもしれません。
しかし、エスケープシーケンスによるクリップボード連携には、文字数制限という大きなデメリットがあります。
また Linux 以外ではきちんと試していませんが、端末エミュレータ自体の機能なので設定値が OS に依存しないはずです。
以上のことから、どちらを利用するか用途に応じて考えていただければと思います。
参加者の反応
今回の発表を聞いた参加者の反応です。
かなり深い知識の話にも、みなさん興味津々です👀
最後に
今回は、echoコマンドでのクリップボードの書き込み・読み込みについてご紹介しました。
注意するべき点もありますので、そこも頭に置きながら活用していただければ幸いです。
株式会社フィックスポイントでは、一緒に働いてくれるメンバーを募集しています!
詳細は、こちらをご覧ください。