tmux

出自 Arch Linux 中文维基

本文內容或本節內容已經過期。

原因: 請提供模板的第一個位置參數以概括原因。 (在Talk:Tmux討論)

本文或本節需要翻譯。要貢獻翻譯,請訪問簡體中文翻譯團隊

附註: 部分內容未翻譯(在 Talk:Tmux# 中討論)

tmux 是一個終端復用器: 可以激活多個終端或窗口, 在每個終端都可以單獨訪問,每一個終端都可以訪問,運行和控制各自的程序.tmux類似於screen,可以關閉窗口將程序放在後台運行,需要的時候再重新連接。

Tmux 與基於 ISC 協議發布的 GNU Screen 類似,這個tmux FAQ 頁面包含兩者的區別。

安裝[編輯 | 編輯原始碼]

官方源安裝軟件包tmux。可選安裝tmux-bash-completion-gitAUR為tmux提供了bash補全功能。

配置[編輯 | 編輯原始碼]

用戶私人配置文件在~/.tmux.conf, 全局配置文件在 /etc/tmux.conf

快捷鍵前綴[編輯 | 編輯原始碼]

前綴為 Ctrl-b
按鍵 動作
c 創建一個新窗口
n 切換至下一窗口
p 切換到上一個窗口
" 水平分割窗口
% 垂直分割窗口
, 重新命名當前窗口
o 移動至下一個面板

默認綁定的前綴按鍵為Ctrl-b. 比如說垂直分割窗口的快捷鍵就是 Ctrl-b %

使用多個面板分割窗口後, 先按前綴快捷鍵(比如說:Ctrl-b)然後按住Ctrl鍵就可以使用方向鍵調整面板大小。 如果要交換面板也是採用同樣的方式,只是按鍵由方向鍵換成「O「鍵。

快捷鍵前綴可以用tmux.conf中的bind和unbind命令修改。比如你可以在配置文件中增加下面命令,把前綴Ctrl-b改成Ctrl-a

unbind C-b
set -g prefix C-a
bind C-a send-prefix
提示:使用特殊字符作為前綴,你必須使用Alt鍵(Meta鍵)代替Ctrl鍵。例如:set -g prefix m-'\'

其他幾種在窗口間移動的快捷鍵:

Ctrl-b l (回到上一个选定的窗口)
Ctrl-b w (显示所有的窗口和窗口序号)
Ctrl-b <window number> (移动到指定序号的窗口, 默认序号是 0 – 9)
Ctrl-b q  (显示当前面板号时, 输入指定的面板号可跳转.)

如果你打開10個以上的面板怎麼辦? tmux有尋找窗口的選項和快捷鍵.

Ctrl-b f <window name> (寻找指定名字的窗口)
Ctrl-b w (从交互式列表中选择窗口)

複製模式[編輯 | 編輯原始碼]

一個tmux窗口可能處於幾個模式中的一個。默認模式允許直接訪問連接到窗口的終端;另一種是複製模式。一旦在複製模式下,你可以在緩衝區包括滾動歷史。vi或emacs風格的按鍵方式綁定在複製模式中,默認是emacs,除非編輯器包含"vi"。

使用下列快捷鍵可以進入滾動模式:

Ctrl-b [

可以在默認編輯器的緩衝區中進行瀏覽。 離開複製模式,使用下面的按鍵: vi模式

 q

emacs模式

 Esc

打開URL[編輯 | 編輯原始碼]

你需要安裝 urlviewAUR來打開URL 另外需要配置如下:

打開一個新的終端:

bind-key u capture-pane \; save-buffer /tmp/tmux-buffer \; run-shell "$TERMINAL -e urlview /tmp/tmux-buffer"

或者直接在tmux的一個新窗口 (不需要新終端):

bind-key u capture-pane \; save-buffer /tmp/tmux-buffer \; new-window -n "urlview" '$SHELL -c "urlview < /tmp/tmux-buffer"'

正確設置 term[編輯 | 編輯原始碼]

如果使用的是 256 色的終端,必須在 tmux 的配置文件 tmux.conf 中將終端設置為 tmuxtmux-256color:

 set -g default-terminal "tmux-256color"  

或在 .bashrc 中添加:

# for tmux: export 256color
[ -n "$TMUX" ] && export TERM=screen-256color

如果你在 tmux.conf 啟用xterm-keys, 那你需要構建一個新的終端信息來聲明新的退出命令,否則程序無法獲取退出方式。用 tic 編譯下列信息,你可以使用 "xterm-screen-256color" 來作為你的TERM:

# A screen- based TERMINFO that declares the escape sequences
# enabled by the tmux config "set-window-option -g xterm-keys".
#
# Prefix the name with xterm- since some applications inspect
# the TERM *name* in addition to the terminal capabilities advertised.
xterm-screen-256color|GNU Screen with 256 colors bce and tmux xterm-keys,

# As of Nov'11, the below keys are picked up by
# .../tmux/blob/master/trunk/xterm-keys.c:
	kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H,
	kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~,
	kRIT=\E[1;2C,

# Change this to screen-256color if the terminal you run tmux in
# does not support bce:
	use=screen-256color-bce,

其他設置[編輯 | 編輯原始碼]

設置最多回滾的行數

set -g history-limit 10000

用systemd後台自啟tmux[編輯 | 編輯原始碼]

開機自啟tmux有諸多好處,當tmux服務在後台運行時,啟動一個tmux會話能減少許多延時。

此外,即使你沒有登錄,對tmux會話的任何定製都將保留,tmux會話也將會被持久化。這對於那些有重度tmux配置(啟動慢)或者共享tmux會話的人來說特別有用。

下面這個systemd service配置可作為參考 (啟動 tmux@username.service):

/etc/systemd/system/tmux@.service
[Unit]
Description=Start tmux in detached session

[Service]
Type=forking
User=%I
ExecStart=/usr/bin/tmux new-session -s %u -d
ExecStop=/usr/bin/tmux kill-session -t %u

[Install]
WantedBy=multi-user.target
提示:可以通過 WorkingDirectory=custom_path 設置工作路徑.

把這個文件放在 systemd/User 目錄下,如 ~/.config/systemd/user/tmux.service. 這樣tmux service 就會在你登錄時自動啟動.

會話初始化[編輯 | 編輯原始碼]

可以通過修改配置文件~/.tmux.conf來使得tmux在初始化一個session的時候自動新建窗口, 比如:

new  -n WindowName Command
neww -n WindowName Command
neww -n WindowName Command

如果想在tmux啟動session的時候自動分割窗口, 只需要把相應分割命令加在你想分割的窗口的neww命令之下, 如下:

new  -s SessionName -n WindowName Command
neww -n foo/bar foo
# 在这之下添加分割窗口命令
splitw -v -p 50 -t 0 bar
selectw -t 1 
selectp -t 0

這將啟動兩個窗口, 第二個窗口會被命名為foo/bar並且會被垂直對半分割, 其中窗格foo會在窗格bar的上面,光標會在第二個窗口(foo/bar)上面的窗格(foo)

{{注意|除非你在你得配置文件.conf中特別指定, 否則會話(session), window(窗口),panes(窗格)的序號都是從0開始算起.}

想要管理多個會話, 需要在你的配置文件中用source命令分別執行相應會話的配置文件

# initialize sessions
bind F source-file ~/.tmux/foo
bind B source-file ~/.tmux/bar

提示和小技巧[編輯 | 編輯原始碼]

啟動時使用默認布局[編輯 | 編輯原始碼]

Session managers like tmuxinator and tmuxp make it easy to manage common session configurations.

For tmuxinator, install tmuxinatorAUR from AUR. Test your installation with

tmuxinator doctor

獲取默認布局參數[編輯 | 編輯原始碼]

Start tmux as usual and configure your windows and panes layout as you like. When finished, get the current layout values by executing (while you are still within the current tmux session)

tmux list-windows

The output may look like this (two windows with 3 panes and 2 panes layout)

0: default* (3 panes) [274x83] [layout 20a0,274x83,0,0{137x83,0,0,3,136x83,138,0[136x41,138,0,5,136x41,138,42,6]}] @2 (active)
1: remote- (2 panes) [274x83] [layout e3d3,274x83,0,0[274x41,0,0,4,274x41,0,42,7]] @3                                         

The Interesting part you need to copy for later use begins after [layout... and excludes ... ] @2 (active). For the first window layout you need to copy e.g. 20a0,274x83,0,0{137x83,0,0,3,136x83,138,0[136x41,138,0,5,136x41,138,42,6]}

定義默認布局[編輯 | 編輯原始碼]

Knowing this, you can exit the current tmux session. Following this, you create your default tmux session layout by editing tmuxinator's config file (Do not copy the example, get your layout values as described above)

~/.tmuxinator/default.yml
name: default
root: ~/
windows:
  - default:
      layout: 20a0,274x83,0,0{137x83,0,0,3,136x83,138,0[136x41,138,0,5,136x41,138,42,6]}
      panes:
        - clear
        - vim
        - clear && emacs -nw
  - remote:
      layout: 24ab,274x83,0,0{137x83,0,0,3,136x83,138,0,4}
      panes:
        - 
        - 

The example defines two windows named "default" and "remote". With your determined layout values. For each pane you have to use at least one - line. Within the first window panes you start the commandline "clear" in pane one, "vim" in pane two and "clear && emacs -nw" executes two commands in pane three on each tmux start. The second window layout has two panes without defining any start commmands.

Test the new default layout with (yes, it is "mux"):

mux default

自動使用默認布局啟動tmux[編輯 | 編輯原始碼]

如果想在啟動終端的時候直接進入tmux, 並且使用默認布局, 可以設置

~/.bashrc
 if [ -z "$TMUX" ]; then
   mux default          
 fi                     

默認會話的替代實現方式[編輯 | 編輯原始碼]

Instead of using the above method, one can just write a bash script that when run, will create the default session and attach to it. Then you can execute it from a terminal to get the pre-designed configuration in that terminal

#!/bin/bash
tmux new-session -d -n WindowName Command
tmux new-window -n NewWindowName
tmux split-window -v
tmux selectp -t 1
tmux split-window -h
tmux selectw -t 1
tmux -2 attach-session -d

Start tmux in urxvt[編輯 | 編輯原始碼]

Use this command to start urxvt with a started tmux session. I use this with the exec command from my .ratpoisonrc file.

urxvt -e bash -c "tmux -q has-session && exec tmux attach-session -d || exec tmux new-session -n$USER -s$USER@$HOSTNAME"

啟動shell時自動啟動tmux[編輯 | 編輯原始碼]

Bash[編輯 | 編輯原始碼]

對bash用戶, 只需要將下面命令添加到自己家目錄下的.bashrc, 要注意這句命令需要在alias配置之前.對其它shell的配置也是類似的

~/.bashrc
# If not running interactively, do not do anything
[[ $- != *i* ]] && return
[[ -z "$TMUX" ]] && exec tmux
注意: 這些代碼確保tmux不會在tmux中啟動(tmux嵌套於tmux中). tmux 通過設置環境變量$TMUX 來設置tmux啟動所用的socket, 如果$TMUX不存在,或者長度為0那麼就可以知道當前沒有運行tmux.

下面的配置會嘗試只啟動一個會話, 當你登錄時, 如果之前啟動過會話, 那麼它會直接attach, 而不是新開一個. 想要新開一個session要麼是因為之前沒有會話, 要麼是你手動啟動一個新的會話.

# TMUX
if which tmux >/dev/null 2>&1; then
    #if not inside a tmux session, and if no session is started, start a new session
    test -z "$TMUX" && (tmux attach || tmux new-session)
fi

下面的配置實現的功能相似, 但是他會在啟動tmux之前先檢查一下tmux是否已經安裝. 它也會在你登出之前幫你重新連接上未關閉的session, 這樣可以讓你手動關閉會話並保存相應的工作,避免數據丟失,進程異常中斷.

# TMUX
if which tmux >/dev/null 2>&1; then
    # if no session is started, start a new session
    test -z ${TMUX} && tmux

    # when quitting tmux, try to attach
    while test -z ${TMUX}; do
        tmux attach || break
    done
fi

另外一種配置, 一樣可以實現自動連接已存在的會話,否則會新開一個:

if [[ -z "$TMUX" ]] ;then
    ID="`tmux ls | grep -vm1 attached | cut -d: -f1`" # get the id of a deattached session
    if [[ -z "$ID" ]] ;then # if not available create a new one
        tmux new-session
    else
        tmux attach-session -t "$ID" # if available attach to it
    fi
fi

啟動non-login shell[編輯 | 編輯原始碼]

Tmux starts a login shell by default, which may result in multiple negative side effects:

  • Users of fortune may notice that quotes are printed when creating a new panel.
  • The configuration files for login shells such as ~/.profile are interpreted each time a new panel is created, so commands intended to be run on session initialization (e.g. setting audio level) are executed.

To disable this behaviour, add to ~/.tmux.conf:

set -g default-command "${SHELL}"

像標籤一樣使用窗口[編輯 | 編輯原始碼]

The following settings added to ~/.tmux.conf allow to use tmux windows like tabs, such as those provided by the reference of these hotkeys — urxvt's tabbing extensions. An advantage thereof is that these virtual 「tabs」 are independent of the terminal emulator.

#urxvt tab like window switching (-n: no prior escape seq)
bind -n S-down new-window
bind -n S-left prev
bind -n S-right next
bind -n C-left swap-window -t -1
bind -n C-right swap-window -t +1

Of course, those should not overlap with other applications' hotkeys, such as the terminal's. Given that they substitute terminal tabbing that might as well be deactivated, though.

It can also come handy to supplement the EOT hotkey Ctrl+d with one for tmux's detach:

bind-key -n C-j detach

Clients simultaneously interacting with various windows of a session[編輯 | 編輯原始碼]

In Practical Tmux[失效鏈接 2021-05-17 ⓘ], Brandur Leach writes:

Screen and tmux's behaviour for when multiple clients are attached to one session differs slightly. In Screen, each client can be connected to the session but view different windows within it, but in tmux, all clients connected to one session must view the same window.
This problem can be solved in tmux by spawning two separate sessions and synchronizing the second one to the windows of the first, then pointing a second new session to the first.

The script 「tmx」 below implements this — the version here is slightly modified to execute 「tmux new-window」 if 「1」 is its second parameter. Invoked as tmx <base session name> [1] it launches the base session if necessary. Otherwise a new 「client」 session linked to the base, optionally add a new window and attach, setting it to kill itself once it turns 「zombie」.

tmx
#!/bin/bash

#
# Modified TMUX start script from:
#     http://forums.gentoo.org/viewtopic-t-836006-start-0.html
#
# Store it to `~/bin/tmx` and issue `chmod +x`.
#

# Works because bash automatically trims by assigning to variables and by 
# passing arguments
trim() { echo $1; }

if [[ -z "$1" ]]; then
    echo "Specify session name as the first argument"
    exit
fi

# Only because I often issue `ls` to this script by accident
if [[ "$1" == "ls" ]]; then
    tmux ls
    exit
fi

base_session="$1"
# This actually works without the trim() on all systems except OSX
tmux_nb=$(trim `tmux ls | grep "^$base_session" | wc -l`)
if [[ "$tmux_nb" == "0" ]]; then
    echo "Launching tmux base session $base_session ..."
    tmux new-session -s $base_session
else
    # Make sure we are not already in a tmux session
    if [[ -z "$TMUX" ]]; then
        echo "Launching copy of base session $base_session ..."
        # Session id is date and time to prevent conflict
        session_id=`date +%Y%m%d%H%M%S`
        # Create a new session (without attaching it) and link to base session 
        # to share windows
        tmux new-session -d -t $base_session -s $session_id
        if [[ "$2" == "1" ]]; then
		# Create a new window in that session
		tmux new-window
	fi
        # Attach to the new session & kill it once orphaned
	tmux attach-session -t $session_id \; set-option destroy-unattached
    fi
fi

A useful setting for this is

setw -g aggressive-resize on

added to ~/.tmux.conf. It causes tmux to resize a window based on the smallest client actually viewing it, not on the smallest one attached to the entire session.

An alternative taken from [1][失效鏈接 2021-11-08 ⓘ] is to put the following ~/.bashrc:

.bashrc
function rsc() {
  CLIENTID=$1.`date +%S`
  tmux new-session -d -t $1 -s $CLIENTID \; set-option destroy-unattached \; attach-session -t $CLIENTID
}

function mksc() {
  tmux new-session -d -s $1
  rsc $1
}

Citing the author:

"mksc foo" creates a always detached permanent client named "foo". It also calls "rsc foo" to create a client to newly created session. "rsc foo" creates a new client grouped by "foo" name. It has destroy-unattached turned on so when I leave it, it kills client.
Therefore, when my computer looses network connectivity, all "foo.something" clients are killed while "foo" remains. I can then call "rsc foo" to continue work from where I stopped.

根據終端類型自動更正TERM環境變量[編輯 | 編輯原始碼]

Instead of setting a fixed TERM variable in tmux, it is possible to set the proper TERM (either screen or screen-256color) according to the type of your terminal emulator:

~/.tmux.conf
## set the default TERM
set -g default-terminal screen

## update the TERM variable of terminal emulator when creating a new session or attaching a existing session
set -g update-environment 'DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY TERM'
## determine if we should enable 256-colour support
if "[[ ${TERM} =~ 256color || ${TERM} == fbterm ]]" 'set -g default-terminal screen-256color'
~/.zshrc
## workaround for handling TERM variable in multiple tmux sessions properly from https://sourceforge.net/p/tmux/mailman/message/32751663/[失效鏈接 2020-08-06 ⓘ] by Nicholas Marriott
if [[ -n ${TMUX} && -n ${commands[tmux]} ]];then
        case $(tmux showenv TERM 2>/dev/null) in
                *256color) ;&
                TERM=fbterm)
                        TERM=screen-256color ;;
                *)
                        TERM=screen
        esac
fi

不用重啟tmux就能加載新的配置[編輯 | 編輯原始碼]

如果對tmux的配置文件~/.tmux.conf做了修改, 默認情況下tmux是不會自動重新加載的, 除非關閉所有正在運行的tmux會話. 如果不想關閉會話而手動加載tmux的配置文件, 可以在命令行下輸入:

tmux source-file <path>

也可以在配置文件 ~/.tmux.conf 中加入下面配置(這樣下次輸入 ctrl+b r就可以加載新的配置文件了):

bind r source-file <path>

還有一種做法是輸入前綴+冒號(ctrl+b :),然後輸入如下命令:

source .tmux.conf

樣例代碼:attach已啟動的會話而不是新開一個[編輯 | 編輯原始碼]

This script checks for a program presumed to have been started by a previous run of itself. Unless found it creates a new tmux session and attaches to a window named after and running the program. If however the program was found it merely attaches to the session and selects the window.

#!/bin/bash

PID=$(pidof $1)

if [ -z "$PID" ]; then
    tmux new-session -d -s main ;
    tmux new-window -t main -n $1 "$*" ;
fi
    tmux attach-session -d -t main ;
    tmux select-window -t $1 ;
exit 0

A derived version to run irssi with the nicklist plugin can be found on its ArchWiki page.

標題欄自動更改[編輯 | 編輯原始碼]

If you SSH into a host in a tmux window, you will notice the window title of your terminal emulator remains to be user@localhost rather than user@server. To allow the title bar to adapt to whatever host you connect to, set the following in ~/.tmux.conf

set -g set-titles on
set -g set-titles-string "#T"

For set-titles-string, #T will display user@host:~ and change accordingly as you connect to different hosts.

自動布局[編輯 | 編輯原始碼]

When creating new splits or destroying older ones the currently selected layout is not applied. To fix that, add following binds which will apply the currently selected layout to new or remaining panes:

bind-key -n M-c kill-pane \; select-layout
bind-key -n M-n split-window \; select-layout

使用類似Vim的快捷鍵設置[編輯 | 編輯原始碼]

See [2] for a configuration friendly to vim users.

With tmux 2.4 change:

bind -t vi-copy 'v' begin-selection
bind -t vi-copy 'y' copy-selection
bind -t vi-copy 'Space' halfpage-down
bind -t vi-copy 'Bspace' halfpage-up

to:

bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'y' send -X copy-selection
bind-key -T copy-mode-vi 'Space' send -X halfpage-down
bind-key -T copy-mode-vi 'Bspace' send -X halfpage-up

常見問題與解答[編輯 | 編輯原始碼]

滾動問題[編輯 | 編輯原始碼]

如果你在終端中使用Shift-PageUp/Shift-PageDown 翻頁有問題,把下面加到配置文件中試試:

set -g terminal-overrides 'xterm*:smcup@:rmcup@'

Shift+F6 not working in Midnight Commander[編輯 | 編輯原始碼]

If the Shift+F6 key combination is not working with either TERM=screen or TERM=screen-256color, then from inside tmux, run this command:

infocmp > screen (or screen-256color)

Open the file in a text editor, and add the following to the bottom of that file:

kf16=\E[29~,

Then compile the file with tic. The keys should be working now.

ICCCM Selection Integration[編輯 | 編輯原始碼]

It is possible to copy a tmux paste buffer to an ICCCM selection, and vice-versa, by defining a shell command which interfaces tmux with an X11 selection interface. The following tmux config file snippet effectively integrates CLIPBOARD with the current tmux paste buffer using xclip:

~/.tmux.conf
...
##CLIPBOARD selection integration
##Requires prefix key before the command key
#Copy tmux paste buffer to CLIPBOARD
bind C-c run "tmux save-buffer - | xclip -i -selection clipboard"
#Copy CLIPBOARD to tmux paste buffer and paste tmux paste buffer
bind C-v run "tmux set-buffer -- \"$(xclip -o -selection clipboard)\"; tmux paste-buffer"

As alternative you can use xsel:

~/.tmux.conf
...
##CLIPBOARD selection integration
##Requires prefix key before the command key
#Copy tmux paste buffer to CLIPBOARD
bind C-c run "tmux show-buffer | xsel -i -b"
#Copy CLIPBOARD to tmux paste buffer and paste tmux paste buffer
bind C-v run "tmux set-buffer -- \"$(xsel -o -b)\"; tmux paste-buffer"

It seems xclip does not close STDOUT after it has read from tmux's buffer. As such, tmux does not know that the copy task has completed, and continues to /await xclip's termination, thereby rendering the window manager unresponsive. To work around this, you can execute the command via run-shell -b instead of run, you can redirect STDOUT of xclip to /dev/null, or you can use an alternative command like xsel.

Urxvt MiddleClick Solution[編輯 | 編輯原始碼]

注意: To use this, you need to enable mouse support

There is an unofficial perl extension (mentioned in the official FAQ[失效鏈接 2020-08-06 ⓘ]) to enable copying/pasting in and out of urxvt with tmux via Middle Mouse Clicking.

First, you will need to download the perl script and place it into urxvts perl lib:

wget http://anti.teamidiot.de/static/nei/*/Code/urxvt/osc-xterm-clipboard
mv osc-xterm-clipboard /usr/lib/urxvt/perl/

You will also need to enable that perl script in your .Xdefaults:

~/.Xdefaults
...
*URxvt.perl-ext-common:		osc-xterm-clipboard
...

Next, you want to tell tmux about the new function and enable mouse support (if you have not already). The third option is optional, to enable scrolling and selecting inside panes with your mouse:

~/.tmux.conf
...
set-option -ga terminal-override ',rxvt-uni*:XT:Ms=\E]52;%p1%s;%p2%s\007'
set-window-option -g mode-mouse on
set-option -g mouse-select-pane on
...

That's it. Be sure to end all instances of tmux before trying the new MiddleClick functionality.

While in tmux, Shift+MiddleMouseClick will paste the clipboard selection while just MiddleMouseClick will paste your tmux buffer. Outside of tmux, just use MiddleMouseClick to paste your tmux buffer and your standard Ctrl-c to copy.

注意: The current tmux version 1.8-1 has a bug where it sometimes might not be possible to paste tmux buffer between different panes of tmux. This behaviour is fixed in the git-version (2013.10.15)

外部鏈接[編輯 | 編輯原始碼]

Forum threads