いい感じのTmux環境を作成できたので、そのプロセスを共有する。
bashrc内で
tmux起動~tmuxのセッション内でコマンド実行
を行う方法はハマりがちなので共有する価値はあると思う。
環境
記事用にvirtualbox内で構築
OS: Lubuntu-20.04.1-desktop-amd54
terminal: qterminal 0.14.1 (Lubuntuにデフォルトで入っているもの)
tmux: 3.0a
tmuxをインストール
sudo apt install tmux
tmuxの設定
- ~/.tmux.confに設定を記述(ファイルがなければ作成)
- tmux source ~/.tmux.confで設定を読み込む
- tmuxのセッションに入って反映されているか確認
見た目調整の設定
prefixキー押下字のステータスバーの名前を反転させる設定は、どこを参照したか忘れてしまった
default-terminalとterminal-overridesの動作の詳細は未調査
# ~/.tmux.conf
# appearance setting
set-option -g status-position top #ステータスバーを下部から上部に変更
set-option -g status-style fg=red,bg=black # タブの表示色を変更
# prefixキーを押したときにステータスバーのユーザ名の色を反転させる
set-option -g status-left '#[fg=cyan,bg=#303030]#{?client_prefix,#[reverse],} #H[#S] #[default]'
set-option -g default-terminal "xterm-256color" #ターミナルに設定したカラースキームをtmuxでも使用する
set-option -ga terminal-overrides ',*256color:Tc' # 同上
操作系の設定
デフォルトのprefixキーCtrl+b は微妙に押しづらいので、Ctrl+tに設定し直した
また、pane間の移動をvimのキーバインドに近いものにした
# ~/.tmux.conf
# operation settings
set-option -g prefix C-t # Ctrl+tをprefixキーに変更
unbind C-b # Ctrl+bをprefixから解除
## vim keybind
bind -r k select-pane -U
bind -r j select-pane -D
bind -r h select-pane -L
bind -r l select-pane -R
## ペインをkillするとき、それが最後のペインでない限り確認なしにkillする
bind -r w if "tmux display -p \"#{session_windows}\" | grep ^1\$ && tmux display -p \"#{window_panes}\" | grep ^1\$" \
"confirm-before -p \"Kill the only pane in the only window? It will kill this session too. (y/n)\" kill-pane" \
"kill-pane"
画面分割機能の設定
画面分割や新しいタブで新しいpaneを作った際に、その新しいシェルのカレントディレクトリは、命令を出したディレクトリではなくホームディレクトリになったしまう。
これは不便だ。
キーバインドを上書きして期待通りにする
# ~/.tmux.comf
bind c new-window -c "#{pane_current_path}"
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
terminal起動時に自動的にtmuxを起動する
tmux内でwindowやpaneを作ったときにもbashrcを読み込んでいるため、
普通に.bashrcにtmuxコマンドを記述すると、無限ループに陥る。
実際は無限ループは起こらないのだが、警告が表示されてダサい。
シェルレベルを判定し、シェルレベル1(terminal起動時)のみtmuxを実行するように記述する
# .bashrc
if [ $SHLVL = 1 ]; then
tmux -2
fi
Tips. terminal起動時のtmux自動実行の際、tmux内でコマンドを実行も自動化したい
htopコマンドやらscreenfetchコマンド、画面分割の命令等、tmux実行時にいつも行う作業は自動的に実行したい
しかしながら.bashrcのif内で
# .bashrc 失敗例
if [ $SHLVL = 1 ]; then
tmux -2
echo hello # これはtmux内で実行されない
fi
としてもechoコマンドを実行する前にtmuxに入っているので、echoコマンドは実行されない
そこで、
- tmuxのセッションをデタッチされた状態で作成
- デタッチされたtmuxセッションに命令を送信
- tmuxセッションにアタッチ
というプロセスを行えばよい
if [ $SHLVL = 1 ]; then
tmux -2 new -d -s SES # SESという名前のセッションをデタッチされた状態で作成
tmux send-key -t SES.0 "echo hello" ENTER # SESに命令を送信
tmux a -t SES # SESにアタッチ
fi
画面分割自動化コマンドの作成
いつも同じレイアウトの画面分割でコーディング作業をしているので、コマンド一発でそのレイアウトになるようにコマンドを作成する
ホームディレクトリに、自作コマンド用のディレクトリを作成
mkdir $HOME/bin
環境変数にディレクトリを追加
この作業は環境によっては不要
.bashrcに追記
# .bashrcに追記
PATH=$PATH:$HOME/bin
これで自作コマンド用のディレクトリを作成できた
自作コマンド
私が使っている画面分割コマンドを紹介
$HOME/bin/tmcというファイル名で保存している
#!/bin/bash
# filename: $HOME/bin/tmc
# exec Desktop
if [ "$1" = "desktop" ]; then
tmux rename-window "Desktop" # タブ名をDesktopに変更
tmux split-window -v -p 67
tmux select-pane -U
tmux split-window -h -p 66
tmux split-window -h -p 35
tmux select-pane -D
tmux split-window -h -p 66
tmux select-pane -U
tmux send-key -t 0 "htop" C-m # pane番号0 でhtopコマンドを実行
tmux send-key -t 1 "screenfetch_view" C-m # screenfetch表示コマンド
tmux send-key -t 2 "tty-clock -c -C 1" C-m # 時計表示コマンド
tmux send-key -t 3 "spt" C-m # spotify-tuiを起動
tmux send-key -t 4 "weather" C-m # 天気予報コマンド
exit
fi
# exec ide
if [ "$1" = "ide" ]; then
tmux rename-window "IDE"
tmux split-window -v -p 20
tmux split-window -h -p 50
tmux select-pane -U
exit
fi
# kill other pane
if [ "$1" = "exit" ]; then
tmux kill-pane -a
exit
fi
# kill window
if [ "$1" = "exit!" ]; then
tmux kill-pane -a
tmux kill-window
exit
fi
# Usage
tmc desktop # トップに載せた画像のようなwindowを作成
tmc ide # コーディング作業用windowを作成
tmc exit # 今居るpane以外のpaneをすべてkill
tmc exit! # windowをkill
参考
@ssh様『tmuxで最後のwindowの最後のpaneであるときだけ確認メッセージを出して、それ以外はそのままkillする』
https://qiita.com/ssh0/items/2c0f0aa1f5179efb02c3
『Tmux open new pane in same directory』
https://gist.github.com/william8th/faf23d311fc842be698a1d80737d9631