在tmux会话之间共享窗口(Windows & Panes)

时间:2024-03-03 21:16:00

去年写过一篇 从Tmux 转到GNU Screen,理由是我可以 在两个显示器上通过PuTTY连接到同一个GNU Screen会话,但两个显示器可以显示不同的窗口(用GNU Screen的术语来说,是window和region),当时认为Tmux是做不到这一点的(如果两个PuTTY窗口attach到同一个会话,一个执行切换窗口的操作,另外一个PuTTY上面也会跟着切换,不能工作在不同窗口上),

但后来发现,其实Tmux支持类似的功能,不过文档中写得有点不太浅显明白.我也是碰到有文章讲这个才发现有这个功能的.

tmux 会话间共享窗口

Tmux实现这个功能依靠的概念是grouped sessions,也就是将建立两个会话(session)并将它们归并到同一个组,同一个组内的多个会话拥有同样的窗口(和窗口里面的pane),但各自有着不同的"当前窗口".创建组的方法是是在创建第二个session的时候用 -t target-session 将前一个session指定为新session的目标session:

new-session [-AdDP] [-c start-directory] [-F format] [-n window-name] [-s session-name]
             [-t target-session] [-x width] [-y height] [shell-command]
               (alias: new)
             Create a new session with name session-name.

             The new session is attached to the current terminal unless -d is given.
             window-name and shell-command are the name of and shell command to
             execute in the initial window.  If -d is used, -x and -y specify the
             size of the initial window (80 by 24 if not given).

             If run from a terminal, any termios(4) special characters are saved and
             used for new windows in the new session.

             The -A flag makes new-session behave like attach-session if session-
             name already exists; in the case, -D behaves like -d to attach-session.

             If -t is given, the new session is grouped with target-session.  This 
             means they share the same set of windows - all windows from target-
             session are linked to the new session and any subsequent new windows or
             windows being closed are applied to both sessions.  The current and
             previous window and any session options remain independent and either
             session may be killed without affecting the other.  Giving -n or shell-
             command are invalid if -t is used.

             The -P option prints information about the new session after it has
             been created.  By default, it uses the format ‘#{session_name}:’ but a 
             different format may be specified with -F.`

然后用 tmux list-sessions 就可以看到有两个session.

bamanzi@raspberrypi:~ $ tmux ls
1: 2 windows (created Tue Jun 27 13:51:20 2017) [204x52] (group 0)
3: 2 windows (created Tue Jun 27 13:59:19 2017) [204x52] (group 0) (attached)

可以看到这里两个会话都有 (group 0) 这个标识.

两个显示器(或者两个人)用 tmux attach -t <id> 分别attached到这两个不同的会话的话,两边可以各自查看不同的窗口.

解决窗口尺寸的问题

不过相对GNU Screen而言,这里还是有个不爽的地方,两个tmux会话之间窗口(window)大小会相互影响:比如一个PuTTY是132x55的,另一个是140x50的,当只有一个session连上来的时候,tmux会将窗口尺寸调整到跟当前PuTTY一致,但组内另外一个窗口连上来的时候,window的大小跟会跟两个屏幕的公共部分一样大了(变成132x50)--这跟同一个tmux session的情况是一样的.

而GNU Screen的设计不太一样,屏幕尺寸是不相互影响的,连region分隔也不相互影响.我们可以在一个PuTTY窗口上显示窗口3和5(GNU Screen的窗口比较类似于Tmux的pane),在另一个PuTTY窗口上显示窗口1, 2和4.窗口大小完全相互不影响--不过它有个烦人的地方,将一个窗口放到当前region来现实的时候,要用C-a F (fit) 调整一下该程序的终端大小,使其跟当前region大小一致.

tmux 提供了一个选项来解决(部分解决)这个问题:

aggressive-resize [on | off]

         Aggressively resize the chosen window.  This means that tmux will resize the window to
         the size of the smallest session for which it is the current window, rather than the
         smallest session to which it is attached.  The window may resize when the current
         window is changed on another sessions; this option is good for full-screen programs
         which sup‐ port SIGWINCH and poor for interactive programs such as shells.

简单翻译一下:当打开这个选项之后,如果两个session显示的当前窗口不是同一个,那么两个session各自根据自己的大小来调整其当前窗口的尺寸(简单理解就是,各自最大化);如果两个session显示同一个窗口,那么还按之前的规则来(缩小到两边的公共面积内).

参考