「ssh先のUbuntuのtmuxでコピーしたテキストをローカルのMacOSのクリップボードに転送する」の版間の差分
(→追記) |
|||
(同じ利用者による、間の4版が非表示) | |||
行23: | 行23: | ||
</pre> | </pre> | ||
− | === | + | === ユーザーログイン後に自動でClipperが動くようにする === |
− | + | Clipperはネットワークポートに送られてくる情報を受け取ってクリップボードに転送してくれるデーモンプロセス的なものらしい。 | |
+ | |||
+ | 起動するには、多分、ログイン後に毎回手動でターミナルに "clipper" とか打てば済むのだとは思うが、めんどいのでログインしたら自動で起動するようにする。 | ||
+ | |||
+ | お好みのコマンドを自動実行するためには、launchctlを使う。plistというフォーマットの設定ファイルを書き、それを~/Library/LaunchAgents/に格納して、launchctlにロードさせれば、plistで設定した通りコマンドが実行されるようになる。らしい。 | ||
+ | |||
+ | plistとか何をどう書けばいいのかわかんないので、とりあえずClipperのGithubリポジトリから取ってきて使うことにする。 | ||
+ | <pre> | ||
+ | # Clipperリポジトリをダウンロード | ||
+ | (MacOS)> git clone https://github.com/wincent/clipper.git | ||
+ | |||
+ | # plistを~/Library/LaunchAgents/ にコピーする | ||
+ | (MacOS)> cp clipper/contrib/darwin/tcp-port/com.wincent.clipper.plist ~/Library/LaunchAgents/ | ||
+ | </pre> | ||
+ | |||
+ | で、[https://github.com/wincent/clipper Clipper] のREADMEに書いてある方法でロードする。 | ||
+ | <pre> | ||
+ | (MacOS)> launchctl load -w -S Aqua ~/Library/LaunchAgents/com.wincent.clipper.plist | ||
+ | </pre> | ||
+ | |||
+ | -wとか-S Aquaとかman読んでも全く意味がわからないが気にしないことにする。 | ||
+ | |||
+ | launchctl list でlaunchctlで管理されているプログラムの一覧が見れるらしいので、確認してみる。 | ||
+ | <pre> | ||
+ | (MacOS)> launchctl list | grep clipper | ||
+ | 69505 0 com.wincent.clipper | ||
+ | </pre> | ||
+ | |||
+ | PID(1列目の数字)が割り当てられているので、loadしただけで起動している様である。 | ||
+ | |||
+ | === sshリモートフォワードの設定 === | ||
+ | sshリモートフォワードを使って、リモート(Ubuntu)の特定のポートに飛んできた情報を、ローカル(MacOS)の特定のポートに転送することが可能である(トンネルを掘る、とか表現される)。この仕組みを使って、リモートのtmuxでコピーしたテキストをリモートのポート8377番に飛ばし、それをリモートフォワードでローカルのポート8377番(※Clipperがlistenするポート)に転送して、Clipperにテキストを流し込み、Clipperがそれをクリップボードに貼り付ける、みたいな流れを作れる。 | ||
+ | |||
+ | ==== sshのコンフィグ書く ==== | ||
+ | 簡単のため、まずは~/.ssh/config に以下の様に設定を書く。DL-Boxはリモート(Ubuntu)のホスト名。 | ||
+ | <pre> | ||
+ | # DL-BoxにClipper用のsshトンネル掘るための設定 | ||
+ | Host DL-Box-Clipper-tunnel | ||
+ | # リモートのIPアドレス | ||
+ | HostName <IPアドレス> | ||
+ | # sshログインのユーザー名 | ||
+ | User <ユーザー名> | ||
+ | # リモートのポート8377番(第一引数)をローカルのポート8377番にリモートフォワードする | ||
+ | RemoteForward 8377 localhost:8377 | ||
+ | # RSA鍵交換でログイン | ||
+ | IdentityFile ~/.ssh/id_rsa | ||
+ | </pre> | ||
+ | |||
+ | ==== トンネル掘る ==== | ||
+ | 上記コンフィグを設定した後なら、 | ||
+ | <pre> | ||
+ | (MacOS)> ssh -fN DL-Box-Clipper-tunnel | ||
+ | </pre> | ||
+ | |||
+ | と叩けばトンネルは開通する(-fはバックグラウンド実行の指定、-Nはsshログイン後に何もコマンドを実行しないことを指定)。これもplist書いてlaunchdにやらせるようにしたいが、とりあえず先へ進む。 | ||
+ | |||
+ | == Clipperの動作確認 == | ||
+ | tmux云々の前に、適当な文字列がリモートからローカルのClipboardへ送れるかをチェックする。ncコマンド(netcat)を使う。ncコマンドは標準入力を特定のホストの特定のポートへ転送するためのコマンドである。 | ||
+ | |||
+ | <pre> | ||
+ | (Ubuntu)> echo 'hoge' | nc localhost 8377 | ||
+ | </pre> | ||
+ | |||
+ | 上記で、hogeという文字列を、リモート(リモートマシンから見ればローカルなのでlocalhostと書いている)のポート8377番へ送り込んでいる。DL-Box:8377→MacOS:8377へのトンネルは開通済みで、かつClipperも起動しているので、上記によりローカルのMacOSのクリップボードに'hoge'という文字列が貼り付けられているはずである。 | ||
+ | |||
+ | 実際 Command + v で貼り付けてみた結果、'hoge'という文字列が貼り付けられた。つまり成功。 | ||
+ | |||
+ | |||
+ | == リモート(Ubuntu)のtmuxの設定 == | ||
+ | tmuxの設定ファイルは ~/.tmux.conf である。ここに表題のことをするための設定を記載する。 | ||
+ | |||
+ | 設定はお好みなのでいろんなやり方があるが、私は以下のようにした。 | ||
+ | |||
+ | ベースにした.tmux.confはこちら → https://qiita.com/komiya_5467/items/ab57eae767b98a765465 | ||
+ | |||
+ | === .tmux.conf全体 === | ||
+ | <pre> | ||
+ | # tmuxを256色表示できるようにする | ||
+ | set-option -g default-terminal screen-256color | ||
+ | set -g terminal-overrides 'xterm:colors=256' | ||
+ | |||
+ | # ステータスバーをトップに配置する | ||
+ | set-option -g status-position top | ||
+ | |||
+ | # 左右のステータスバーの長さを決定する | ||
+ | set-option -g status-left-length 90 | ||
+ | set-option -g status-right-length 90 | ||
+ | |||
+ | # #P => ペイン番号 | ||
+ | # 最左に表示 | ||
+ | set-option -g status-left '#H:[#P]' | ||
+ | |||
+ | # Wi-Fi、バッテリー残量、現在時刻 | ||
+ | # 最右に表示 | ||
+ | set-option -g status-right '[%Y-%m-%d(%a) %H:%M]' | ||
+ | |||
+ | # ステータスバーを1秒毎に描画し直す | ||
+ | set-option -g status-interval 1 | ||
+ | |||
+ | # センタライズ(主にウィンドウ番号など) | ||
+ | set-option -g status-justify centre | ||
+ | |||
+ | # ステータスバーの色を設定する | ||
+ | set-option -g status-bg "colour238" | ||
+ | |||
+ | # status line の文字色を指定する。 | ||
+ | set-option -g status-fg "colour255" | ||
+ | |||
+ | # vimのキーバインドでペインを移動する | ||
+ | bind h select-pane -L | ||
+ | bind j select-pane -D | ||
+ | bind k select-pane -U | ||
+ | bind l select-pane -R | ||
+ | |||
+ | # vimのキーバインドでペインをリサイズする | ||
+ | bind -r H resize-pane -L 5 | ||
+ | bind -r J resize-pane -D 5 | ||
+ | bind -r K resize-pane -U 5 | ||
+ | bind -r L resize-pane -R 5 | ||
+ | |||
+ | # | でペインを縦分割する | ||
+ | bind | split-window -h | ||
+ | |||
+ | # - でペインを縦分割する | ||
+ | bind - split-window -v | ||
+ | |||
+ | # 番号基準値を変更 | ||
+ | set-option -g base-index 1 | ||
+ | |||
+ | # マウス操作を有効にする | ||
+ | set-option -g mouse on | ||
+ | bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'" | ||
+ | |||
+ | # コピーモードを設定する | ||
+ | # コピーモードでvimキーバインドを使う | ||
+ | setw -g mode-keys vi | ||
+ | |||
+ | # 'v' で選択を始める | ||
+ | bind -T copy-mode-vi v send -X begin-selection | ||
+ | |||
+ | # 'V' で行選択 | ||
+ | bind -T copy-mode-vi V send -X select-line | ||
+ | |||
+ | # 'C-v' で矩形選択 | ||
+ | bind -T copy-mode-vi C-v send -X rectangle-toggle | ||
+ | |||
+ | # 'y' でヤンク | ||
+ | bind -T copy-mode-vi y send -X copy-selection | ||
+ | |||
+ | # 'Y' で行ヤンク | ||
+ | bind -T copy-mode-vi Y send -X copy-line | ||
+ | |||
+ | # 'C-p'でペースト | ||
+ | bind-key C-p paste-buffer | ||
+ | |||
+ | bind-key -T copy-mode-vi v send -X begin-selection | ||
+ | bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "nc localhost 8377" | ||
+ | bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "nc localhost 8377" | ||
+ | bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc localhost 8377" | ||
+ | </pre> | ||
+ | |||
+ | === ポイント === | ||
+ | .tmux.confの以下の部分。 | ||
+ | <pre> | ||
+ | bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "nc localhost 8377" | ||
+ | bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "nc localhost 8377" | ||
+ | bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc localhost 8377" | ||
+ | </pre> | ||
+ | |||
+ | MacOSローカルのtmuxの場合は "nc localhost 8377" が "pbcopy" なんじゃないかと思う。pbcopyは標準入力をクリップボードに送るためのコマンド。今回はその代わりに、Clipperの動作チェックでも使用したncコマンドを使って、ポート8377番にコピー内容を転送している。 | ||
+ | |||
+ | 実際に上記のconfでテストしたところ表題の件には成功した。リモートかローカルか区別・意識すること無く、MacOSの Command + c, Command + v でコピペできるようになった。 | ||
+ | |||
+ | |||
+ | == トラブルシューティング == | ||
+ | === sshセッションが切れるとコピペできなくなる... === | ||
+ | <pre> | ||
+ | (MacOS)> echo hogefuga | nc localhost 8377 | ||
+ | (MacOS)> pbpaste | ||
+ | hogefuga | ||
+ | </pre> | ||
+ | |||
+ | ローカルでポート8377番に文字列流し込んだら、pbpaste(クリップボードにある文字列を出力するコマンド)で文字列取り出せたので、Clipperは生きている。 | ||
+ | |||
+ | <pre> | ||
+ | (MacOS)> ssh -fN DL-Box-Clipper-tunnel | ||
+ | Warning: remote port forwarding failed for listen port 8377 | ||
+ | </pre> | ||
+ | |||
+ | トンネル切れてんのかと思って再度通そうとするもなんか警告出るし、リモートのtmuxとのコピペもできない。 | ||
+ | |||
+ | |||
+ | リモートの側でsshd再起動してみた。 | ||
+ | <pre> | ||
+ | (Ubuntu)> sudo systemctl restart sshd | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | それから再度ローカルでトンネルつなぎ直し。 | ||
+ | <pre> | ||
+ | (MacOS)> ssh -fN DL-Box-Clipper-tunnel | ||
+ | </pre> | ||
+ | |||
+ | 今度は警告が出ずにコマンド実行できた。 | ||
+ | |||
+ | で、tmuxとのコピペにも成功した。 | ||
+ | |||
+ | よくわからないが、とりあえずリモートでsshd再起動して、ローカルでリモートフォワードし直せば、なんか復旧する。 |
2019年8月26日 (月) 12:35時点における最新版
目次
この記事について
表題の通りのことをやってみる。Clipperというプログラムを活用する。参考にしたのはClipperのREADMEと、こちらのページ → https://blog.freedom-man.com/tmux
2019年8月26日実施。
実行環境
リモート
- Ubuntu 16.04.6 LTS
- tmux 2.9a
ローカル
- MacOS Mojave 10.14.6
ローカル(MacOS)側準備
Clipperのインストール
まずはMacOSにClipperをインストールする。Homebrew(パッケージマネージャ)を使う。
clipperのインストールはtmuxセッション内で実行してはいけないらしい。まるで理由がわからないが。
(MacOS)> brew install clipper
ユーザーログイン後に自動でClipperが動くようにする
Clipperはネットワークポートに送られてくる情報を受け取ってクリップボードに転送してくれるデーモンプロセス的なものらしい。
起動するには、多分、ログイン後に毎回手動でターミナルに "clipper" とか打てば済むのだとは思うが、めんどいのでログインしたら自動で起動するようにする。
お好みのコマンドを自動実行するためには、launchctlを使う。plistというフォーマットの設定ファイルを書き、それを~/Library/LaunchAgents/に格納して、launchctlにロードさせれば、plistで設定した通りコマンドが実行されるようになる。らしい。
plistとか何をどう書けばいいのかわかんないので、とりあえずClipperのGithubリポジトリから取ってきて使うことにする。
# Clipperリポジトリをダウンロード (MacOS)> git clone https://github.com/wincent/clipper.git # plistを~/Library/LaunchAgents/ にコピーする (MacOS)> cp clipper/contrib/darwin/tcp-port/com.wincent.clipper.plist ~/Library/LaunchAgents/
で、Clipper のREADMEに書いてある方法でロードする。
(MacOS)> launchctl load -w -S Aqua ~/Library/LaunchAgents/com.wincent.clipper.plist
-wとか-S Aquaとかman読んでも全く意味がわからないが気にしないことにする。
launchctl list でlaunchctlで管理されているプログラムの一覧が見れるらしいので、確認してみる。
(MacOS)> launchctl list | grep clipper 69505 0 com.wincent.clipper
PID(1列目の数字)が割り当てられているので、loadしただけで起動している様である。
sshリモートフォワードの設定
sshリモートフォワードを使って、リモート(Ubuntu)の特定のポートに飛んできた情報を、ローカル(MacOS)の特定のポートに転送することが可能である(トンネルを掘る、とか表現される)。この仕組みを使って、リモートのtmuxでコピーしたテキストをリモートのポート8377番に飛ばし、それをリモートフォワードでローカルのポート8377番(※Clipperがlistenするポート)に転送して、Clipperにテキストを流し込み、Clipperがそれをクリップボードに貼り付ける、みたいな流れを作れる。
sshのコンフィグ書く
簡単のため、まずは~/.ssh/config に以下の様に設定を書く。DL-Boxはリモート(Ubuntu)のホスト名。
# DL-BoxにClipper用のsshトンネル掘るための設定 Host DL-Box-Clipper-tunnel # リモートのIPアドレス HostName <IPアドレス> # sshログインのユーザー名 User <ユーザー名> # リモートのポート8377番(第一引数)をローカルのポート8377番にリモートフォワードする RemoteForward 8377 localhost:8377 # RSA鍵交換でログイン IdentityFile ~/.ssh/id_rsa
トンネル掘る
上記コンフィグを設定した後なら、
(MacOS)> ssh -fN DL-Box-Clipper-tunnel
と叩けばトンネルは開通する(-fはバックグラウンド実行の指定、-Nはsshログイン後に何もコマンドを実行しないことを指定)。これもplist書いてlaunchdにやらせるようにしたいが、とりあえず先へ進む。
Clipperの動作確認
tmux云々の前に、適当な文字列がリモートからローカルのClipboardへ送れるかをチェックする。ncコマンド(netcat)を使う。ncコマンドは標準入力を特定のホストの特定のポートへ転送するためのコマンドである。
(Ubuntu)> echo 'hoge' | nc localhost 8377
上記で、hogeという文字列を、リモート(リモートマシンから見ればローカルなのでlocalhostと書いている)のポート8377番へ送り込んでいる。DL-Box:8377→MacOS:8377へのトンネルは開通済みで、かつClipperも起動しているので、上記によりローカルのMacOSのクリップボードに'hoge'という文字列が貼り付けられているはずである。
実際 Command + v で貼り付けてみた結果、'hoge'という文字列が貼り付けられた。つまり成功。
リモート(Ubuntu)のtmuxの設定
tmuxの設定ファイルは ~/.tmux.conf である。ここに表題のことをするための設定を記載する。
設定はお好みなのでいろんなやり方があるが、私は以下のようにした。
ベースにした.tmux.confはこちら → https://qiita.com/komiya_5467/items/ab57eae767b98a765465
.tmux.conf全体
# tmuxを256色表示できるようにする set-option -g default-terminal screen-256color set -g terminal-overrides 'xterm:colors=256' # ステータスバーをトップに配置する set-option -g status-position top # 左右のステータスバーの長さを決定する set-option -g status-left-length 90 set-option -g status-right-length 90 # #P => ペイン番号 # 最左に表示 set-option -g status-left '#H:[#P]' # Wi-Fi、バッテリー残量、現在時刻 # 最右に表示 set-option -g status-right '[%Y-%m-%d(%a) %H:%M]' # ステータスバーを1秒毎に描画し直す set-option -g status-interval 1 # センタライズ(主にウィンドウ番号など) set-option -g status-justify centre # ステータスバーの色を設定する set-option -g status-bg "colour238" # status line の文字色を指定する。 set-option -g status-fg "colour255" # vimのキーバインドでペインを移動する bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R # vimのキーバインドでペインをリサイズする bind -r H resize-pane -L 5 bind -r J resize-pane -D 5 bind -r K resize-pane -U 5 bind -r L resize-pane -R 5 # | でペインを縦分割する bind | split-window -h # - でペインを縦分割する bind - split-window -v # 番号基準値を変更 set-option -g base-index 1 # マウス操作を有効にする set-option -g mouse on bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'" # コピーモードを設定する # コピーモードでvimキーバインドを使う setw -g mode-keys vi # 'v' で選択を始める bind -T copy-mode-vi v send -X begin-selection # 'V' で行選択 bind -T copy-mode-vi V send -X select-line # 'C-v' で矩形選択 bind -T copy-mode-vi C-v send -X rectangle-toggle # 'y' でヤンク bind -T copy-mode-vi y send -X copy-selection # 'Y' で行ヤンク bind -T copy-mode-vi Y send -X copy-line # 'C-p'でペースト bind-key C-p paste-buffer bind-key -T copy-mode-vi v send -X begin-selection bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "nc localhost 8377" bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "nc localhost 8377" bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc localhost 8377"
ポイント
.tmux.confの以下の部分。
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "nc localhost 8377" bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "nc localhost 8377" bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc localhost 8377"
MacOSローカルのtmuxの場合は "nc localhost 8377" が "pbcopy" なんじゃないかと思う。pbcopyは標準入力をクリップボードに送るためのコマンド。今回はその代わりに、Clipperの動作チェックでも使用したncコマンドを使って、ポート8377番にコピー内容を転送している。
実際に上記のconfでテストしたところ表題の件には成功した。リモートかローカルか区別・意識すること無く、MacOSの Command + c, Command + v でコピペできるようになった。
トラブルシューティング
sshセッションが切れるとコピペできなくなる...
(MacOS)> echo hogefuga | nc localhost 8377 (MacOS)> pbpaste hogefuga
ローカルでポート8377番に文字列流し込んだら、pbpaste(クリップボードにある文字列を出力するコマンド)で文字列取り出せたので、Clipperは生きている。
(MacOS)> ssh -fN DL-Box-Clipper-tunnel Warning: remote port forwarding failed for listen port 8377
トンネル切れてんのかと思って再度通そうとするもなんか警告出るし、リモートのtmuxとのコピペもできない。
リモートの側でsshd再起動してみた。
(Ubuntu)> sudo systemctl restart sshd
それから再度ローカルでトンネルつなぎ直し。
(MacOS)> ssh -fN DL-Box-Clipper-tunnel
今度は警告が出ずにコマンド実行できた。
で、tmuxとのコピペにも成功した。
よくわからないが、とりあえずリモートでsshd再起動して、ローカルでリモートフォワードし直せば、なんか復旧する。