Abstract
The terminal in Linux/BSD/Unix is often seen as an extremely powerful and fundamental tool of the system, and with good reason. However, there are many cases in which having a plethora of terminal windows opened is all but required to accomplish a task; that is where tools such as tmux and GNU screen come in. These tools allow for managing terminal windows just like a window manager would manage graphical windows. Most people that have been using modern Unix-like systems are familiar with tmux; however, screen is an older utility that many people often don’t reach for to solve the same problems and more.
What is a Terminal Multiplexer and Why is it Useful
Let’s start at the premise of the tool itself, what does a terminal multiplexer do? From Wikipedia’s opening paragraph on the topic:
A terminal mutliplexer is a software application that can be used to multiplex several separate pseudoterminal-based login sessions inside a single terminal display, terminal emulator window, PC/workstation system console, or remote login session, or to detach and reattach sessions from a terminal. It is useful for dealing with multiple programs from a command line interface, and for separating programs from the session of th eUnix shell taht started the program, particularly so a remote process continues running even when the user is disconnected.
In short, it a piece of software that allows for turning one terminal session into multiple, as well as allowing a terminal based application to run in a background session without requiring a terminal to be left opened. This is something that would be really useful in a time where computers were not very powerful and opening another window could be a problem, however, it’s 2025 and computers are massively overpowered compared to what they were twenty years ago. Why would anyone use a terminal multiplexer these days? The main benefit I have from it is the organization options that being able to group multiple terminal windows into one terminal session provides. If I am working on some writing, I can keep all the things related to that writing (SSH sessions, w3m sessions, and the text editor) opened all in one terminal window, along with being able to name each window to make it easy to figure out where I am.
The other main use would be to keep a semi interactive terminal command running in the background; an example of this might be a Minecraft server. The server software itself is not one that daemon-izes well (at least from what I’ve been told) and it would really be better to keep it running properly in the background. Terminal multiplexers allow sending a process to the background then easily recalling that process in a more intuitive way than something like standard job control.
Basic Key Bindings
Before getting into how to actually use GNU screen, I am going to start off with a small guide for hotkeys. This will hopefully help reduce some of the confusion on how to actually make things happen after invoking the screen application.
The activation hotkey for GNU screen is ctrl+a, or as it is written in the documentation, C-a. This hotkey will then prompt screen to listen for other keys to do various things depending on which key is pressed. For example, the hotkey ‘c’ (so pressing C-a then c) will create another window within screen, and the hotkey ’“’ (so C-a then”) would show a list of all the windows that are opened in screen at the moment as well as letting the user switch to a particular window. There is quite a list of keybindings that screen will recognize, however, I will also give a small list of some of the ones that I use most often to get people started with something a bit less overwhelming than what the man pages provides.
- C-a “: Present a list of all windows for selection.
- C-a 0…9: Switch to window number 0…9, or the blank window (window number corresponds to the number pressed on keyboard).
- C-a Tab: Switch the input focus to the next region.
- C-a C-a: Toggle to the window displayed previously. If this windows does no longer exist, other has the same effect as next.
- C-a A: Allow user to enter a title for the current window.
- C-a c: Creates a new window with a shell and switch to that window.
- C-a d: Detach screen from this terminal.
- C-a k: Destroy the current window.
- C-a K: Destroy the current window without confirmation.
- C-a S: Split the current region horizontally into two new ones.
- C-a ?: Show key bindings.
- C-a : Kill all windows and terminate screen.
- C-a [: Enter copy/scrollback mode. The scrolling of this mode uses vi like bindings for movement, and to copy text, press the ‘enter’ key to select where to start the copying text, then move to the end of the selection that needs to be copied, and press ‘enter’ again.
- C-a ]: Write the contents of the paste buffer to the stdin queue of the current window. To paste the previously copied text, simply use the binding, nothing special here.
- C-a |: Split the current region vertically into two new ones.
In large part, I just re-used the verbiage from the man page for those commonly used commands, because I found it rather self-explanatory with only a few items needing some clarification (at least in my opinion).
Using Screen
Actually using GNU screen is not terribly difficult especially with
the assistance of a cheat sheet for hotkeys (whether that be the one
from above or the built in one). To start the application, simply type
screen
then press enter in a terminal window, and a shell
will launch in a screen window. From there, any of the hotkeys can be
invoked to do their corresponding action.
After some use, the user might want to close the terminal window, but
keep the session itself alive; In other words, detach from the session.
That can be done simply by using the ‘C-a d’ hotkey, but then what?
Screen appears to be closed, but how would one go about re-attaching to
that session? If only one screen session is active in the background,
then running screen -d -r
will re-attach to the opened
session. However, if multiple screen sessions are opened, then screen
will complain with the following:
There are several suitable screens on:
6648.pts-1.hostname (Detached)
16954.pts-1.hostname (Detached)
Type "screen [-d] -r [pid.]tty.host" to resume one of them.
The two main ways to overcome this are to force screen to choose, which will re-attach to the most recently opened session. I want to stress here, that most recently opened does not necessarily mean the same thing as the most recently attached session. For example, if the user opens two sessions, screen will choose the second session even if the user re-attached to the first session after creating the second. This will remain true until either the second session is closed or a third session is opened, in which case screen will default to the first or third session respectively.
The second option to re-attach to the sessions is to give the PID of the screen session as an argument as follows:
# list the screen sessions:
screen -ls
There are screens on:
8428.pts-1.hostname (Detached)
6648.pts-1.hostname (Detached) # We will re-attach to this session
16954.pts-1.hostname (Detached)
3 Sockets in /run/screens/S-user.
# Then re-attach to the session, 6648 in this example
screen -d -r 6648
What do the ‘-d’ and ‘-r’ flags do specifically though? Well, according to the man page:
-d|-D [pid.tty.host] does not start screen, but detaches the elsewhere running screen session. It has the same effect as typing C-a d from screen’s controlling terminal. -D is the equivalent to the power detach key. If no session can be detached, this option is ignored. In combination with the -r/-R option more powerful effects can be achieved:
-d -r Reattach a session and if necessary detach it first.
-d -R Reattach a session and if necessary detach or even create it first.
-d -RR Reattach a session and if necessary detach or create it. Use the first session if more than one session is available.
-D -r Reattach a session. If necessary detach and logout remotely first.
-D -R Attach here and now. In detail this means: If a session is running, then reattach. If necessary detach and logout remotely first. If it was not running create it and notify the user. This is the author’s favorite.
-D -RR Attach here and now. Whatever that menas, just do it.
Note: It is always a good idea to check the status of your sessions by means of screen -list.
For single user systems, the difference between ‘-d -r’ and ‘-D -R’ should not be very noticeable, however, on multi-user systems understanding the difference between the permutations of the ‘-d’, ‘-r’, and ‘-RR’ flags may be useful. It is also worth noting that the ‘-list’ and ‘-ls’ flags do the same thing, ‘-ls’ is just less typing, and thus is usually better.
One last useful thing that GNU screen can do is attaching to serial connections. This isn’t something that I do often, however, it is extremely useful when I need it. To attach to a serial connection with screen, simply run:
screen /dev/ttyUSB0
Screen will automagically negotiate the baud rate and attach to the serial connection (assuming that ttyUSB0 is the correct serial connection). There are obviously other tools that can do this, but it is helpful to have more tools in the bag in the event something else might work better. In this case, being able to copy and paste something like a switch config via screen might be useful.
Customizing Screen
Customizing GNU screen is generally done via an rc file, however, can
also be done by running commands with ‘C-a :’ within a screen session.
The rc file for GNU screen is just a file that will tell screen a list
of commands to run which will then provide the customizations that the
user desires. For example, my .screenrc
file is fairly
simplistic at time of writing:
startup_message off
hardstatus alwayslastline
hardstatus string "screen (%n: %t)"
caption always '%{=7;0}%Y-%m-%d %c %-Lw%{+b 5;0}{%n %t]%{-}%+Lw%=%{-}'
The specifics of each of these commands, as well as a complete list of all available commands, is available on the screen man page. It is a rather exhaustive list, so I will not be going over it in detail here. In short, my screen rc file turns off the startup message that opens in each new screen session (unless you turn it off), then use the other three lines to create a kind of simple status bar within my screen sessions. However, much more advanced things can certainly be done with the exhaustive list of commands that screen will recognize.
Additionally, the keybindings can be re-assigned if they are not to your liking. Simply by using the bind command. This command will allow binding any key to and command; this can be paired with the ‘unbindall’ command to be able to completely re-map all of the shortcuts GNU screen can handle.
Closing Thoughts
GNU Screen is not the flashiest terminal multiplexer available, not even in the open source world, however, it is one that has been tried and tested for over 30 years. This isn’t a tool that is going to completely revolutionize how you interact with a terminal, or even be a tool that is opened on a regular basis, but it is a tool that is nice to be installed in the system and have a basic understanding of how to use. It can make managing terminal windows much easier in an event where you may need to open lots of them, and it certainly makes dealing with serial connections suck slightly less. Give it a try and see if it improves your workflow on a terminal, or if it is just a hindrance.