tmux 嵌套 tmux_Tmux实践:本地和嵌套远程tmux会话

tmux 嵌套 tmux

by Alexey Samoshkin

通过阿列克谢·萨莫什金(Alexey Samoshkin)

Tmux实践:本地和嵌套远程tmux会话 (Tmux in practice: local and nested remote tmux sessions)

我们讨论了tmux功能,它们与本地和远程方案的相关性以及如何设置和配置tmux以支持嵌套会话 (We discuss tmux features, their relevance for local and remote scenarios, and how to setup and configure tmux to support nested sessions)

This is the first part of my tmux in practice article series. It is about using and configuring tmux v2, local and remote tmux sessions usage, and how to support a scenario when a remote tmux session is going to be nested inside a local tmux session.

这是我的tmux实践文章系列的第一部分。 它是关于使用和配置tmux v2,本地和远程tmux会话的用法,以及如何支持将远程tmux会话嵌套在本地tmux会话中的情况。

Before you start reading, here is a working example from my machine. We have a local tmux session on OSX inside iTerm2 (run in full screen mode). The local session has 2 windows: “zsh” and “node”.

在开始阅读之前,这是我机器上的一个有效示例 。 我们在iTerm2中的OSX上有一个本地tmux会话(以全屏模式运行)。 本地会话有2个窗口:“ zsh”和“ node”。

The “zsh” window is split into 2 panes: in both panes we SSH’ed to the remote hosts (CentOS7 and Ubuntu14) and jump into remote tmux sessions there.

“ zsh”窗口分为两个窗格:在两个窗格中,我们都通过SSH方式连接到远程主机(CentOS7和Ubuntu14),然后跳到那里的远程tmux会话。

The bottom pane with the Ubuntu14 remote session is further split into 2 panes, and we have 3 windows: shell, mon, and logs.

带有Ubuntu14远程会话的底部窗格进一步分为2个窗格,我们有3个窗口:shell,mon和log。

If you’re curious how it all works together, continue reading.

如果您好奇如何将它们一起使用,请继续阅读。

特征 (Features)

First let’s quickly go through tmux features and advantages, to understand their relevance to local or remote scenarios. We should clarify to ourselves why we need this “nested tmux in tmux” thing, because at first glance it looks pretty crazy.

首先,让我们快速浏览tmux的功能和优点,以了解它们与本地或远程方案的相关性。 我们应该向自己说明为什么我们需要这种“嵌套的tmux in tmux”,因为乍一看它看起来非常疯狂。

  1. Terminal multiplexing, named windows, split window into several panes.This makes more sense for the local environment, when you decide to supercharge your terminal emulator, which otherwise does not support aforementioned features. For example, iTerm or Terminator are already capable of multiplexing a terminal.

    终端多路复用(称为窗口)将窗口分为几个窗格。 当您决定为终端仿真器增压时,这对于本地环境更有意义,否则它将不支持上述功能。 例如,iTerm或Terminator已经能够复用终端。

  2. Setup and kick off tmux session with a pre-configured set of windows and panes, their arrangement, and commands run inside to avoid hassle of repeatedly setting up them again and again from scratch. For example:

    使用一组预先配置的窗口和窗格,它们的排列和命令来设置和启动tmux会话,以避免麻烦地从头开始反复设置它们。 例如:

    - “dev” session, which includes the “#1: shell” window with 2 panes for ad-hoc usage

    -“开发”会话,其中包括“#1:shell”窗口,其中包含2个用于临时使用的窗格

    - “#2: monitoring” window with

    -带有“#2:监视”窗口

    htop and sysdig panes

    htopsysdig窗格

    - “#3: log” window with

    -“#3:日志”窗口,其中包含

    journalctl and tail -f app.log panes

    journalctltail -f app.log窗格

    - “#4: node” window running

    -运行“#4:节点”窗口

    node server

    node服务器

    tmux lets you write script to achieve this, and if you prefer the configuration-like approach, take a look at

    tmux允许您编写脚本来实现此目的,如果您喜欢类似配置的方法,请查看

    tmuxinator. This is relevant for both local and remote scenario.

    灭鼠药 。 这与本地和远程方案有关。

  3. Persist your working state, so you can detach and resume later with the same state as you left. When working locally with several projects, you can setup several per-project tmux sessions and switch context easily

    保持您的工作状态,因此您可以分离并稍后以与离开时相同的状态继续。 在本地处理多个项目时,可以设置多个每个项目的tmux会话并轻松切换上下文

    On the remote machine, you can detach from session by the end of a working day, and get back to the same session from home at evening.

    在远程计算机上,您可以在工作日结束之前脱离会话,并在晚上在家中返回同一会话。

  4. Survive abrupt connection drops.This is one of the most important feature. Suppose, you SSH onto remote host, and have a long-running process there. If SSH connection is lost or physical network drop occurs, SIGHUP signal would be sent to the remote shell, and it and all its child processes would be terminated. Tmux makes your remote processes resistant to such risks.

    避免突然的连接中断。 这是最重要的功能之一。 假设您将SSH连接到远程主机,并在该主机上运行了很长时间。 如果SSH连接丢失或发生物理网络断开,则SIGHUP信号将发送到远程Shell,并且它将终止其所有子进程。 Tmux使您的远程进程可以抵御此类风险。

Less important features, but still worth mention are as follows:

不太重要的功能,但仍然值得一提的如下:

  1. Once you setup tmux environment, you are less dependent on the parent terminal emulator and its unique set of features, and can switch to another terminal emulator will less hassle. Given I’m an iTerm2 on OSX user, I can migrate to Terminator or konsole on Linux by installing my tmux configuration there, and get the very same known environment I am already used to.

    设置tmux环境后,您将不再依赖于父终端仿真器及其独特的功能集 ,并且可以切换到另一个终端仿真器将减少麻烦。 鉴于我是OSX上的iTerm2用户,因此可以通过在Linux上安装tmux配置迁移到Linux上的Terminator或konsole,并获得与我已经习惯的相同的已知环境。

  2. Share your remote session with your colleague, so you can collaborate in real time. I think it’s of rare use in a real world, but sounds cool. Yeah, pair programming, and other cool buzzwords. ?

    与您的同事共享远程会话,以便您可以实时协作。 我认为它在现实世界中很少使用,但听起来很酷。 是的,结对编程和其他流行词汇。 ?

So, to conclude, tmux is responsible for two main things:

因此,总而言之, tmux负责两件事

  1. Terminal multiplexing, session/window/pane management

    终端多路复用,会话/窗口/窗格管理
  2. Persist session state and survive disconnects for remote scenarios

    保持会话状态,并在远程方案中保持断开连接状态

Where tmux really shines is (2). Regarding (1), some people argue, that tmux breaks Unix philosophy, because it’s trying to do 2 things, instead of doing one and doing it well, and that (1) should not be a tmux responsibility.

tmux真正发光的地方是(2)。 关于(1), 有人争论说 ,tmux破坏了Unix哲学,因为它试图做两件事,而不是一味地做得很好,并且(1)不应该是tmux的责任。

嵌套的本地和远程会话 (Nested local and remote sessions)

So, given all that, some people prefer using tmux on the local machine only on top of their terminal emulator, supercharging it with multiplexing and window management in the first place. People who spent most of their time SSH’ing on remote hosts, make use of persistent session nature and resistance to network disconnects.

因此,考虑到所有这些,有些人更喜欢仅在其终端仿真器之上在本地计算机上使用tmux,首先使用多路复用和窗口管理对其进行增压。 大部分时间都在远程主机上使用SSH进行访问的人利用了持久的会话性质和对网络断开的抵抗力。

But do local and remote cases have to be mutually exclusive? Can I combine them? Yes, it’s legal to SSH to a remote host and start the tmux session there, while already being in a tmux environment locally.

但是本地案例和远程案例是否必须互斥? 我可以结合起来吗? 是的,在本地已经处于tmux环境中的情况下,SSH到远程主机并在其中启动tmux会话是合法的。

This is called nested sessions, but comes with some obstacles:

这称为嵌套会话,但存在一些障碍:

First of all, you face the question: How you can control inner sessions, since all keybindings are caught and handled by outer sessions?

首先,您将面临一个问题: 由于所有键绑定都是由外部会话捕获和处理的,因此如何控制内部会话?

The most common solution is to press prefix twice (prefix is a keybinding that puts tmux in a command mode, usually it’s C-b, but some people prefer remapping it to screen-likeC-a). The first prefix keystroke is caught by the outer session, whereas second is passed to the inner session. No extra steps need to be done, and this works out of the box.

最常见的解决方案是按两次prefix (前缀是将tmux置于命令模式的键绑定,通常是Cb ,但有些人喜欢将其重新映射为类似于屏幕的Ca )。 第一个前缀键击被外部会话捕获,而第二个则传递给内部会话。 无需执行任何额外的步骤,即可立即使用。

However, root keybindings — those which are listened globally, not in command mode — are still caught by the outer session only. And I found it’s really annoying to double press prefix. For me it’s even annoying to press it once, in iTerm2 there is no such thing as command mode, and I just press “⌘⌥→” to select pane on the right, instead of sending two separate keystrokes C-a RightArrow.

但是,根键绑定(那些全局监听而不是在命令模式下监听的键绑定)仍然仅被外部会话捕获。 而且我发现双按prefix真的很烦。 对我来说,按一次它甚至很烦人,在iTerm2中没有命令模式之类的东西,我只是按“ ⌘⌥→ ”以选择右侧的窗格,而不是发送两次单独的击键Ca RightArrow

Another solution is to setup 2 individual prefixes, for example, C-b for a local session, while C-a for a remote one. With the configuration below, it means that pressing C-a locally would send default prefix C-b to the remote session. Found this solution here.

另一种解决方案是设置2个单独的前缀,例如, Cb用于本地会话,而Ca用于远程会话。 使用以下配置,这意味着在本地按Ca会将默认前缀Cb发送到远程会话。 在这里找到此解决方案。

set -g prefix C-bbind-key -n C-a send-prefix

But it really feels like:

但这确实感觉像:

The better solution would be using same key table both on local and remote sessions — no separate prefixes or double pressing prefix — and turn off all keybindings and prefix handling in the outer session, when working with inner one. Credits and this Github issue.

更好的解决方案是在本地和远程会话上使用相同的密钥表-不使用单独的前缀或双击前缀-并在使用内部会话时关闭外部会话中的所有键绑定和前缀处理。 鸣谢Github问题

So, when I’m going to work in the inner session, I just press F12 and toggle OFF mode in the outer session. When that happens, the outer session shows the OFF visual indicator in the status line and changes the visual styling of status line to further stress that the session in in OFF mode.

因此,当我要在内部会话中工作时,只需按F12并在外部会话中切换OFF模式即可。 发生这种情况时,外部会话将在状态行中显示OFF视觉指示器,并更改状态行的视觉样式,以进一步强调该会话处于OFF模式。

Here is a Gist from my working tmux configuration, which I crafted recently (only relevant pieces are included):

这是我最近使用的tmux配置要点 (仅包含相关内容):

Basically, we setup F12 keybinding for the root key table. When pressed, we set prefix to None, switch current key table to off, then change the styles of status line, and force tmux to refresh the status line. An extra step is taken to cancel the current pane copy mode, if it is present. As soon as we switched to off for the key table and turned off prefix handling, the outer session does not listen for any keystrokes at all. All keystrokes are passed to the inner session without being intercepted by the outer one.

基本上,我们为根键表设置F12键绑定。 当按下时,我们将前缀设置为None ,将当前键表切换为off ,然后更改状态行的样式,并强制tmux刷新状态行。 如果存在当前窗格复制模式,则需要采取额外的步骤来取消它。 一旦我们off了密钥表并关闭了前缀处理,外部会话就根本不会监听任何击键。 所有击键都传递给内部会话,而不会被外部会话拦截。

That’s all great, but we need somehow to get back and turn the outer session back into normal working mode. That’s why we setup a single keybinding F12 in key table off, which reverts the effect of initial F12 key press.

一切都很好,但是我们需要以某种方式返回并将外部会话恢复为正常工作模式。 这就是为什么我们在键表off设置单个键绑定F12的原因,它可以恢复初始F12按键的效果。

Also, we configure a visual indicator for the status line, which shows on when current key table is off, and hides otherwise.

此外,我们为状态行配置了一个可视指示器,当当前键表off时该指示器会亮起,否则会隐藏。

To conclude, given this configuration, you can setup a single local session with 1 window with 2 panes that contains nested remote sessions to different hosts (see image at the beginning of the post).

总之,使用此配置,您可以使用1个窗口和2个窗格来设置单个本地会话,其中包含2个窗格,这些窗格包含到不同主机的嵌套远程会话(请参见文章开头的图像)。

远程特定的会话配置 (Remote-specific session configuration)

In the previous example you might notice that the status line of the outer session is positioned at the top, where the inner session has its status line at the bottom. That provides a nice visual distinction and does not make the status lines stack on top of each other.

在前面的示例中,您可能会注意到外部会话的状态行位于顶部,内部会话的状态行位于底部。 这提供了很好的视觉区别,并且不会使状态行彼此堆叠。

But how is it possible to apply different conditional-based configurations?

但是如何应用不同的基于条件的配置呢?

Well, that’s rather easy. We can detect whether the session is remote or local by existence of the SSH_CLIENT environment variable.

好吧,那很容易。 我们可以通过存在SSH_CLIENT环境变量来检测会话是远程会话还是本地会话。

if-shell 'test -n "$SSH_CLIENT"' \   'source-file ~/.tmux/tmux.remote.conf'

And the ~/.tmux/tmux.remote.conf file contains the configuration which will be applied only to the remote session. There we change status line position, and remove some widgets from it (like clock and battery) because they just replicate same widgets from the local session.

~/.tmux/tmux.remote.conf文件包含仅将应用于远程会话的配置。 在那里,我们更改状态行的位置,并从中删除一些小部件(例如时钟和电池),因为它们只是从本地会话中复制相同的小部件。

So, that’s it. If you want to see all this in action, check out my tmux-config repository.

就是这样了。 如果您想查看所有这些信息,请查看我的tmux-config存储库。

tmux/tmux: tmux source code — https://github.com/tmux/tmux

tmux / tmux:tmux源代码— https://github.com/tmux/tmux

Using Tmux Remotely Within a Local Tmux Session | Simply Ian — https://simplyian.com/2014/03/29/using-tmux-remotely-within-a-local-tmux-session/

在本地Tmux会话中远程使用Tmux 简单的伊恩-https: //simplyian.com/2014/03/29/using-tmux-remotely-within-a-local-tmux-session/

Nested tmux — http://stahlke.org/dan/tmux-nested/

嵌套的tmux- http: //stahlke.org/dan/tmux-nested/

toggle on/off all keybindings · Issue #237 · tmux/tmux — https://github.com/tmux/tmux/issues/237

启用/禁用所有键绑定·问题#237·tmux / tmux — https://github.com/tmux/tmux/issues/237

samoshkin/tmux-config: Tmux configuration, that supercharges your tmux to build cozy and cool terminal environment — https://github.com/samoshkin/tmux-config

samoshkin / tmux-config:Tmux配置,可以使您的tmux增压以构建舒适而凉爽的终端环境— https://github.com/samoshkin/tmux-config

翻译自: https://www.freecodecamp.org/news/tmux-in-practice-local-and-nested-remote-tmux-sessions-4f7ba5db8795/

tmux 嵌套 tmux