1. Introduction
The tmux terminal multiplexer is a terminal user interface (TUI) application for more convenient handling of a text-only command-line environment. Although tmux provides isolation of screens, we might still break a pseudo-terminal that it provides.
In this tutorial, we talk about tmux panes and ways to stop and restart them. First, we briefly refresh our knowledge about the tmux interface hierarchy. After that, we delve into ways of killing and respawning elements of the latter.
We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments unless otherwise specified.
2. tmux Hierarchy
At the top of the tmux hierarchy, we have sessions. Each session contains at least one pseudo-terminal (PTY, pty), but there are usually many.
Within a session, we can create tmux windows. Just like in a graphical user interface (GUI), each window can be moved, named, or closed.
Any of the windows can be further subdivided into panes. In a way, this bottom level reaches through to the top since each pane is a different PTY.
By pressing the default tmux Meta combination Ctrl+B and then w, we get to a top-level view of the whole hierarchy:
(0) - 0: 1 windows (attached)
(1) └─> - 0: [tmux]* (2 panes)
(2) ├─> 0: bash "web"
(3) └─> 1: bash "web"
┌ 0 (sort: index)────────────────────────┐
│ baeldung@web:~# │baeldung@web:~# │
│ │ │
│ │ │
│ ┌───┐ │ ┌───┐ │
│ │ 0 │ │ │ 1 │ │
│ └───┘ │ └───┘ │
│ │ │
│ │ │
└─────────────────────────────────────────┘
[0] 0:[tmux]*Z "web" 06:56 06-Jun-23
Here, we see a single (attached) session (0) with 1 window. The window (1) has (2 panes) – 0 and 1. Both of them run bash on the web host. Moreover, we get a simple TUI visualization.
Although terminal emulators generally protect against overloaded terminals, terminal multiplexers provide an extra layer of protection. Even so, we can have the same issues on a per-pane basis:
- long-running commands
- hung commands
- problematic output
- unresponsive input
Moreover, since each pane is its own terminal, we might need to restore or restart a particular pane due to, e.g., its shell environment.
3. tmux Pane Restart
In case a pane presents issues, we have a couple of options.
3.1. Kill an Offending Child Process
Being at the base of an operating system (OS), shells and terminals rarely have bugs that cause them to hang. Thus, it’s often a child process that may cause a tmux pane terminal to hang or need a restart.
So, we can try to stop the process via a local interrupt like Ctrl+C.
Failing that, there are also ways to remotely signal that process to stop:
- find an offending process as a child via its parent shell or terminal
- kill the process via its PID
If we can’t free or remedy the pane ourselves, there might be a need to kill or respawn it.
3.2. Kill Session, Pane, or Window
As with most environments, tmux offers kill-* commands:
- Ctrl+B :kill-session – kill the active session, all its windows and panes
- Ctrl+B :kill-window or Ctrl+B & – kill the active window and all panes within it
- Ctrl+B :kill-pane or Ctrl+B x – kill the active pane
There’s also an alternative to the manual commands and entries above:
- press Ctrl+W to bring up the current tmux hierarchy
- use the Up Arrow and Down Arrow keys to select a given object (potentially expanding lists via the Right Arrow key)
- press x (a Kill prompt should appear at the bottom)
- press y to kill the selected object
Each command destroys the relevant level of the hierarchy and all levels below it. Because of this, we lose all progress and data within their environments. So, this is a method of last resort.
3.3. Respawn Pane or Window
In addition, there are :respawn-* commands for panes and windows in tmux:
- Ctrl+B :respawn-window – stop and restart a window
- Ctrl+B :respawn-pane – stop and restart a pane
Trying these on an active window or pane fails unless we supply the [-k]ill flag:
:respawn-pane -k 0
Here, we kill pane 0. Actually, not using -k only works when a pane was spawned with the remain-on-exit option. In that case, instead of exiting, we’re left with a dead pane once the command within it exits.
Critically, if we kill the last window, the tmux session ends. Further, killing a window stops all panes within.
3.4. Rebuild Layout
While it also doesn’t preserve the pane contents, we can save and rebuild our layout from a saved string:
$ tmux list-windows -t 0
0: bash* (2 panes) [63x30] [4a78,63x30,0,0{31x30,0,0,0,31x30,32,0,1}] @0 (active)
Here, we use the tmux command to list-windows for session 0. The resulting string 4a78,63×30,0,0{31×30,0,0,0,31×30,32,0,1} contains multiple comma-separated fields:
- 4a78: checksum
- 63×30: window size
- 0,0: window coordinates
- {31×30,0,0,0}: pane 0 size, coordinates, and ID
- {31×30,32,0,1}: pane 1 size, coordinates, and ID
Now, we can use such a layout string with select-layout:
$ tmux select-layout -t 1 '4a78,63x30,0,0{31x30,0,0,0,31x30,32,0,1}'
At this point, we should have our original window and pane setup from session 0 duplicated in session 1 as well.
4. Summary
In this article, we talked about killing and restarting a tmux pane.
In conclusion, tmux is versatile enough to provide mechanisms for killing, respawning, and reordering its design elements, even when conventional methods might not work.