多窗口管理器Tmux - 從入門到精通

tmux 的基本概念

咱們先來理解下 tmux 的幾個元素。tmux 的主要元素分爲三層git

  • Session 一組窗口的集合,一般用來歸納同一個任務。session 能夠有本身的名字便於任務之間的切換。
  • Window 單個可見窗口。Windows 有本身的編號,也能夠認爲和 ITerm2 中的 Tab 相似。
  • Pane 窗格,被劃分紅小塊的窗口,相似於 Vim 中 C-w +v 後的效果。

下面是三個元素在 tmux 中的具體展示
圖片.pnggithub

安裝需求

若是要安裝 tmux, 須要先安裝 libevent 2.0 以上版本shell

不然會出現以下錯誤:vim

control.c: In function ‘control_callback’:
control.c:63: warning: implicit declaration of function ‘evbuffer_readln’
control.c:63: error: ‘EVBUFFER_EOL_LF’ undeclared (first use in this function)
control.c:63: error: (Each undeclared identifier is reported only once
control.c:63: error: for each function it appears in.)
control.c:63: warning: assignment makes pointer from integer without a cast
make: *** [control.o] Error 1

安裝 tmux

下載 tmux

https://github.com/tmux/tmux/releases/download/2.0/tmux-2.0.tar.gzwindows

下載 libevent

http://sourceforge.net/projects/levent/?source=typ_redirectruby

編譯安裝 libevent

./configure --prefix=/home/harriszh/app && make && make install

由於考慮到不少用戶在服務器上沒有 root 權限,因此這裏安裝到 home 目錄下bash

編譯安裝 tmux

setenv CFLAGS "-L/home/harriszh/app/lib -I/home/harriszh/app/include" && ./configure --prefix=/home/harriszh/app && make && make install

若是沒有前面的 setenv, 那麼會遇到下面的錯誤服務器

alerts.o: In function `alerts_queue':
alerts.c:(.text+0xa0): undefined reference to `event_initialized'
cmd-capture-pane.o: In function `cmd_capture_pane_exec':
cmd-capture-pane.c:(.text+0x549): undefined reference to `evbuffer_pullup'
cmd-capture-pane.c:(.text+0x554): undefined reference to `evbuffer_get_length'
cmd-load-buffer.o: In function `cmd_load_buffer_callback':
cmd-load-buffer.c:(.text+0x2cd): undefined reference to `evbuffer_get_length'
cmd-load-buffer.c:(.text+0x2f9): undefined reference to `evbuffer_pullup'
cmd-pipe-pane.o: In function `cmd_pipe_pane_exec':
cmd-pipe-pane.c:(.text+0x221): undefined reference to `evbuffer_get_length'
cmd-run-shell.o: In function `cmd_run_shell_callback':
cmd-run-shell.c:(.text+0x297): undefined reference to `evbuffer_get_length'
cmd-run-shell.c:(.text+0x33a): undefined reference to `evbuffer_pullup'
control-notify.o: In function `control_notify_input':
control-notify.c:(.text+0x4f0): undefined reference to `evbuffer_pullup'
control-notify.c:(.text+0x4fb): undefined reference to `evbuffer_get_length'
control.o: In function `control_callback':
control.c:(.text+0x26): undefined reference to `evbuffer_readln'
format.o: In function `format_cb_pane_tabs':
format.c:(.text+0x69c): undefined reference to `evbuffer_get_length'
format.c:(.text+0x6c8): undefined reference to `evbuffer_get_length'
format.c:(.text+0x6da): undefined reference to `evbuffer_pullup'
format.o: In function `format_job_complete':
format.c:(.text+0xb1c): undefined reference to `evbuffer_get_length'
format.c:(.text+0xb52): undefined reference to `evbuffer_pullup'
format.o: In function `format_create':
format.c:(.text+0x3a0a): undefined reference to `event_initialized'
...

配置使用

下面是 cshell 的環境配置session

setenv LD_LIBRARY_PATH /home/harriszh/app/lib
set path=(/home/harriszh/app/bin:$path)

打開 tmux

在命令行輸入 tmux, 看看可否打開。
我遇到了 tmux 配置文件的問題,我在~/.tmux.conf 裏把不支持的命令註釋掉了app

定製化

能夠直接使用 gpakosz 的 tmux, 安裝方法以下

$ cd
$ rm -rf .tmux
$ git clone https://github.com/gpakosz/.tmux.git
$ ln -s .tmux/.tmux.conf
$ cp .tmux/.tmux.conf.local .

要獲取效果,能夠直接tmux source ~/.tmux.conf

若是要使用近似 powerline 效果,能夠在~/.tmux.conf.local 裏註釋 129-132 行, 打開 133-136 行
圖片.png

使用

console 命令

開啓會話: tmux new -s <session-name>
斷開會話: tmux deattach
接入以前的會話: tmux a -t <session-name>
關閉會話: tmux kill-session -t <session-name>
關閉窗口: tmux kill-session -t <session-name>
關閉 tmux: tmux killall
建立一個新的 window: tmux new-window
列出窗口: tmux list-windows
0-9 根據索引轉到該 window: tmux select-window -t
重命名當前 window: tmux rename-window
將 window 垂直劃分爲兩個 pane: tmux split-window
將 window 水平劃分爲兩個 pane: tmux split-window -h
在指定的方向交換 pane: tmux swap-pane -[UDLR]
在指定的方向選擇下一個 pane: tmux select-pane -[UDLR]
查看全局設定: tmux show-options -g
查看窗口設定: tmux show-options -w
查看remote設定: tmux show-options -s

下面的命令須要先按 prefix 鍵

基礎

? 獲取幫助信息

會話管理

s 列出全部會話
$ 重命名當前的會話
d 斷開當前的會話
D 選擇要脫離的會話;在同時開啓多個會話時使用
[ 複製模式,光標移動到複製內容位置,空格鍵開始,方向鍵選擇複製,回車確認,q/Esc 退出
] 粘貼模式,粘貼以前複製的內容,按 q/Esc 退出
t 顯示當前時間

窗口管理

c 建立一個新窗口
& 關閉當前窗口
l 先後窗口間互相切換
. 修改當前窗口編號,至關於從新排序
f 在全部窗口中查找關鍵詞
, 重命名當前窗口
w 列出全部窗口
% 水平分割窗口
" 豎直分割窗口
n 選擇下一個窗口
p 選擇上一個窗口
0~9 選擇 0~9 對應的窗口

窗格管理

% 建立一個水平窗格
" 建立一個豎直窗格
h 將光標移入左側的窗格*
j 將光標移入下方的窗格*
l 將光標移入右側的窗格*
k 將光標移入上方的窗格*
q 顯示窗格的編號
o 在窗格間切換
} 與下一個窗格交換位置
{ 與上一個窗格交換位置
ctrl+方向鍵 以 1 個單元格爲單位移動邊緣以調整當前窗格大小
alt+方向鍵 以 5 個單元格爲單位移動邊緣以調整當前窗格大小
alt+o 逆時針旋轉當前窗格
ctrl+o 順時針旋轉當前窗格
z 最大化當前所在窗格
Page up 向上滾動屏幕,q 退出
Page down 向下滾動屏幕,q 退出
! 在新窗口中顯示當前窗格
x 關閉當前窗格> 要使用帶「*」的快捷鍵須要提早配置,配置方法能夠參考上文的「在窗格間移動光標」一節。——譯者注

其餘

t 在當前窗格顯示時間
[ 進入 copy-paste 模式,這時能夠滾動窗口來選擇

copy mode

在gpakosz/.tmux.git裏的配置裏已經爲copy mode重設了類vi快捷鍵
但在個人某個環境裏它們一直不工做,我花了幾個小時終於搞清楚了緣由
在源代碼key-bindings.c裏,有下面chars

"bind -Tcopy-mode C-Space send -X begin-selection",
    "bind -Tcopy-mode C-a send -X start-of-line",
    "bind -Tcopy-mode C-c send -X cancel",
    "bind -Tcopy-mode C-e send -X end-of-line",
    "bind -Tcopy-mode C-f send -X cursor-right",
    "bind -Tcopy-mode C-b send -X cursor-left",
    "bind -Tcopy-mode C-g send -X clear-selection",
    "bind -Tcopy-mode C-k send -X copy-end-of-line",
    "bind -Tcopy-mode C-n send -X cursor-down",
    ...
    "bind -Tcopy-mode-vi Space send -X begin-selection",
    "bind -Tcopy-mode-vi '$' send -X end-of-line",
    "bind -Tcopy-mode-vi , send -X jump-reverse",
    "bind -Tcopy-mode-vi / command-prompt -p'(search down)' 'send -X search-forward \"%%%\"'",
    "bind -Tcopy-mode-vi 0 send -X start-of-line",

一開始我經過C-a :來手工輸入bind -Tcopy-mode-vi Space send -X begin-selection,但發現仍是沒用, 特別是後來我注意到要用C-Space, 而不是Space, 我才意識到有兩種模式, copy-modecopy-mode-vi. 試了一下手工輸入bind -Tcopy-mode Space send -X begin-selection果真就好了。 再經過網上查到了進入vi mode(set-window-option -g mode-keys vi)的方法並打入到.tmux.conf後,一切問題迎刃而解。

安裝 tmuxinator

tmuxinator 是 tmux 的配置管理工具, 解決了 tmux 服務器關機後 session 丟失問題。tmuxinator 能夠根據配置文件快速建立 tmux 的 session。

gem install tmuxinator

在$HOME/.tmuinator/.tmuxinator.bash 裏新建

#!/usr/bin/env bash

_tmuxinator() {
    COMPREPLY=()
    local word
    word="${COMP_WORDS[COMP_CWORD]}"

    if [ "$COMP_CWORD" -eq 1 ]; then
        local commands="$(compgen -W "$(tmuxinator commands)" -- "$word")"
        local projects="$(compgen -W "$(tmuxinator completions start)" -- "$word")"

        COMPREPLY=( $commands $projects )
    elif [ "$COMP_CWORD" -eq 2 ]; then
        local words
        words=("${COMP_WORDS[@]}")
        unset words[0]
        unset words[$COMP_CWORD]
        local completions
        completions=$(tmuxinator completions "${words[@]}")
        COMPREPLY=( $(compgen -W "$completions" -- "$word") )
    fi
}

complete -F _tmuxinator tmuxinator mux

而後在$HOME/.bashrc 裏增長

source $HOME/.tmuxinator/.tmuxinator.bash
export EDITOR='vim'

source $HOME/.bashrc 使其生效

若是用的是 zhs, 使用下面文件

_tmuxinator() {
  local commands projects
  commands=(${(f)"$(tmuxinator commands zsh)"})
  projects=(${(f)"$(tmuxinator completions start)"})

  if (( CURRENT == 2 )); then
    _describe -t commands "tmuxinator subcommands" commands
    _describe -t projects "tmuxinator projects" projects
  elif (( CURRENT == 3)); then
    case $words[2] in
      copy|debug|delete|open|start)
        _arguments '*:projects:($projects)'
      ;;
    esac
  fi

  return
}

tmuxinator 經常使用命令

mux n ws # 建立工程 ws
mux o ws # 打開工程 ws 的配置文件
mux e ws # 同上
mux c ws ws1 # 複製 ws 工程到 ws1
mux d ws # 刪除 ws 工程
mux l # 顯示全部工程
mux ws # 開啓 ws 工程

配置

在 new 一個工程後,會打開一個文本

name: ws # session名稱
root: ~/ # 工程根目錄,活動Pane會首先cd到此目錄

windows:
  - editor: # 第1個名爲Editor的Window
      layout: main-vertical # Pane的佈局
      panes: # 各個Pane
        - vim # 第一個Pane運行vim命令
        - guard # 第二個Pane運行guard命令
  - server: bundle exec rails s # 第2個名爲server的Window,運行命令爲bundle
  - logs: tail -f log/development.log # 第3個名爲logs的Window,運行命令爲tail

能夠修改上面的 editor, server, logs (window 名)
或者 panes 下面的各個 panes 要執行的命令, 若是什麼也不執行,就寫上-

bug fix

在 tmuxinator 裏,刪除工程時會報以下錯誤

$ tmuxinator d ws
Are you sure you want to delete ws?(y/n) y
/usr/local/lib/ruby/gems/2.4.0/gems/tmuxinator-0.9.0/lib/tmuxinator/cli.rb:220:in `block in delete': uninitialized constant Tmuxinator::Cli::FileUtils (NameError)
Did you mean?  FileTest
    from /usr/local/lib/ruby/gems/2.4.0/gems/tmuxinator-0.9.0/lib/tmuxinator/cli.rb:215:in `each'
    from /usr/local/lib/ruby/gems/2.4.0/gems/tmuxinator-0.9.0/lib/tmuxinator/cli.rb:215:in `delete'
    from /usr/local/lib/ruby/gems/2.4.0/gems/thor-0.20.0/lib/thor/command.rb:27:in `run'
    from /usr/local/lib/ruby/gems/2.4.0/gems/thor-0.20.0/lib/thor/invocation.rb:126:in `invoke_command'
    from /usr/local/lib/ruby/gems/2.4.0/gems/thor-0.20.0/lib/thor.rb:387:in `dispatch'
    from /usr/local/lib/ruby/gems/2.4.0/gems/thor-0.20.0/lib/thor/base.rb:466:in `start'
    from /usr/local/lib/ruby/gems/2.4.0/gems/tmuxinator-0.9.0/bin/tmuxinator:15:in `<top (required)>'
    from /usr/local/bin/tmuxinator:23:in `load'
    from /usr/local/bin/tmuxinator:23:in `<main>'

須要在/usr/local/lib/ruby/gems/2.4.0/gems/tmuxinator-0.9.0/lib/tmuxinator/cli.rb 第 2 行加上

require 'fileutils'

總結

tmux最大的好處是能夠保存狀態,對於登陸到服務器工做的人,能夠節省大量時間,並且多窗口省去了開很是多窗口切換的時間。使用它能夠極大提升工做效率。並且可定製化,相較於同類瓦片式窗口管理器,提供了更多的定製和快捷鍵,是同類軟件中的佼佼者。

相關文章
相關標籤/搜索