Here are notes on how to use the program called screen
which is a
terminal multiplexer. The GNU
Screen home page can be hard to find thanks to the indistinct name.
Customize Settings
My first suggestion before even running screen would be to customize the settings for screen. For example, using "Ctrl-a" for screen’s escape key is, in my opinion, crazy. Ctrl-a is used for too many other things (beginning of a line in bash and most other ncurses environments). I like to use Ctrl-g which rarely conflicts with anything.
To do this, add:
escape ^gg
to your ~/.screenrc
file.
The second setting I would recommend is to keep an active status line
running. These are called "captions" in screen
terminology. There
are several reasons to have one:
-
It alerts you to when
screen
is running. It can be hard to tell if you’re in a screen session or not otherwise. The status line makes it clear. -
There is a clock on the status line. You may have a clock on your wrist but the point of a clock here is that over an ssh connection, the screen will be refreshed about once per second at a minimum. This is useful for not letting connections drop.
-
The status line allows you to see exactly what windows you have open.
To get a decent status line use something like my favorite:
caption always " %w --- %c:%s"
My .screenrc looks like this:
caption always " %w --- %c:%s"
escape ^gg # only seriously conflicts with mutt
vbell on # default: off
vbell_msg " -- vbell_msg!! -- " # default: "Wuff,Wuff!!"
startup_message off # default: on
defscrollback 1000 # default: 100
autodetach on
pow_detach_msg "Screen session of \$LOGNAME \$:cr:\$:nl:ended."
Starting Screen
To use screen you just type screen
to start initially. If you’re
using a "caption" or status bar, you should see that. If not you can
type echo $STY
and it should show you something. If you’re not in a
screen session, then it won’t.
Restarting After A Power Outage
When your server running a complex screen session dies, restoring all the terminals to the way you like them can be tedious. Here is script that shows the basic technique.
#!/bin/bash # Chris X Edwards - 2021-10-07 - screen_reboot.sh # This script is to recover my complex screen sessions after a power # outage. It is a good place to record the setup details of my screen # terminals and what they should be doing. # === Start Main Session === S=Xed_main_session if screen -S $S -list; then echo "WARNING! There is an existing screen session called: $S" echo "Press [C]-c to abort this, or Enter to DELETE that session and replace it with a new one." read fi # Delete any sessions with the main session name just in case. screen -S $S -list |\ grep $S |\ awk '{print $1}' |\ while read SS; do \ echo $SS screen -S $SS -X quit done # Start new main session in background. # `-d -m` starts detached allowing this script to continue tweaking. screen -S ${S} -d -m # === Basic Setup Of Each Window === # 1. Create a new screen terminal. (First is present automatically.) # 2. Set title of this screen terminal. # 3. Send a command to window. Repeat as needed. # Helpful for simulating "enter" presses after commands. NL=$(echo -ne '\015') # (Present by default.) # Mail client. screen -S ${S} -p 1 -X title "mu" screen -S ${S} -p 1 -X stuff "mu${NL}" screen -S ${S} -X screen 2 # Help notes screen -S ${S} -p 2 -X title "h" screen -S ${S} -p 2 -X stuff "cd /home/xed/X/web/live/help/${NL}" screen -S ${S} -p 2 -X stuff "clear${NL}" # etc... # Reattach this screen and start using. screen -r ${S} -p 1
Screen Actions
Now you can use the screen session. You can:
-
New - Make more windows with <screen_escape_key>+c
-
Next - Switch to the next window with <screen_escape_key>+n or <screen_escape_key>+<space>
-
Previous -Switch to the previous window with <screen_escape_key>+p
-
Jump - Switch to a specific screen window with <screen_escape_key>+<number> where number is the number of the screen window.
-
Recent - Switch back and forth between two (of the most recent) screen windows with <screen_escape_key>+<screen_escape_key>. This is very handy.
-
Name - Name windows if you have a caption/status line with <screen_escape_key>+[S]-A. That’s a captital A. After typing that key sequence, you can edit the id of the window for the current session. Usually it just says
bash
(or your shell). I like to rename it to something short that reminds me what’s going on in that window. -
Kill - Kill stuck windows. Sometimes bad things happen and you have to kill a window. Use <screen_escape_key>+[S]-K. It will politely ask for confirmation.
-
Shutdown - To close all windows and stop screen <screen_escape_key>+\ .
-
Reset - You can use
/usr/bin/reset
to recover from dumping a screen full of binary (causing who-knows-what terminal settings madness) or just use <screen_escape_key>+[S]-Z -
Select - Have too many screens open? Try <screen_escape_key>+" to get a menu of them.
-
Monitor - Want to know when some activity has happened on one of the screens? Use <screen_escape_key>+[S]-M. Then the name in the status bar will invert when there is new activity. Not only can you monitor for activity, but you can monitor for a lack of activity. Perhaps you are waiting for a compile to finish, you can do <screen_escape_key>+[S]-_ and when 15 seconds have gone by with nothing changing, you’ll get the inverted name indicator. Consider shortening the time needed to register inactivity with the
silencewait 5
command (shown here setting to 5 seconds). -
Log - With <screen_escape_key>+[S]-H, screen activity is written to
screenlog.n
. Use a second time to toggle log writing off. -
Help - <screen_escape_key>+[S]-?. Note that what this shows is missing some things that are found in the man page which might be a better reference.
Checking For Screen Status
Sometimes you have scripts that should be run in a screen session (e.g. minecraft or octoprint servers). How do you know if you’re properly in a screen session?
if [ "${TERM::6}" == screen ]; then echo "Screen session OK"; else echo "NOT in a screen"; exit 1 ;fi
Put this in your script and it will patiently stop to allow you to start the screen session.
Splitting
I used to use screen splitting but since screen only supported horizontal splitting and I usually wanted vertical, I just stopped worrying about it. But these days (later than 2016-12-10, version 4.05.00), screen seems to do just fine splitting vertically so maybe worth doing. Since I forgot the splitting bindings, I’ll put them here.
-
<screen_escape_key>+[S]-S - splits horizontally.
-
<screen_escape_key>+| - (pipe) splits horizontally.
-
<screen_escape_key>+<tab> - focuses different split regions.
-
<screen_escape_key>+[S]-X - Removes a split region, but not the "screen" which continues to do what it was doing, in the background if necessary.
-
<screen_escape_key>+x - Locks screen session, but also collapses all regions into a single one on unlocking. (Use normal user passwd.)
Detaching
When you are finished working with your screen windows but you wish for them to continue working without you, you need to "detach" them. One way to do this is to kill the client side of the ssh connection or kill the terminal it is running in. This works because screen is designed to carry on even if inadvertently interrupted. But there is a more polite way to detach. Use <screen_escape_key>+d. Now screen should be running but not interactively in your terminal session. You can log out or close your terminal.
When you want to reconnect to the running screen session, use this command:
$ screen -rd
Now you should be back where you were when you detached. Note that you
can also reattach in a new physical location even if you didn’t
detach. For example, if you are at your office and working on a
screen session and you go to a computer at home after logging in with
ssh
, you can run screen -rd
and the session that was running on
your office computer will detach and start running on your home
computer. This is extremely handy!
Multiple Attachments
Sometimes I have a complicated situation where I’m reading a long thing on one screen window but I need a different screen window open on a different computer (or different non-contiguous monitor). Screen can re-attach multiple simultaneous times.
:->[host1][~]$ screen -rd
....
:->[host2][~]$ screen -rx
The -x
option allows screen sessions that are already attached to be
attached again. They then become pretty much exact mirrors and can be
operated independently. When both connections share the same screen
window like this, both have equal control. This could be useful for
having two people edit the exact same thing at the exact same time.
This could be useful for teaching or pair programming.
Quitting Screen
To stop using screen completely, log out of all windows and screen will quit. It’s good to do this before turning off machines. Once a machine is turned off, no screen sessions can be reattached.
If your computer hosting the screen session loses power, you’ll have
to clean up the screen session. Use screen -wipe
to get ride of any
dead sessions.
Named Sessions
It is also possible to have multiple screen sessions. I use this so
that different projects have their own session saving me from cycling
through windows from an irrelevant project. To get different sessions,
you need to name them. Just use a -S <name>
option when starting
screen or reattaching a named session. The name can be pretty much
whatever you want.
Note
|
Looks like Centos7 is overly helpful with this. When you change
a session’s name, it gets overwritten immediately upon execution of
the next program. I found this to be extremely aggravating. To give an
example of the problem, if you set a name like log and then run cat
log the name instantly changes to something like user@host:dir .
This may be Red Hat’s new overly helpful help conflicting with my
longstanding screen configuration. The cure is to find this in
/etc/bashrc and comment it out: |
# are we an interactive shell? if [ "$PS1" ]; then if [ -z "$PROMPT_COMMAND" ]; then case $TERM in # xed- please stop "helping" me. This messes up status bar name captions. # screen*) # if [ -e /etc/sysconfig/bash-prompt-screen ]; then # PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen # else # PROMPT_COMMAND='printf "\033k%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"' # fi # ;;
Or, just after the esac
add this to undo the damage.
unset PROMPT_COMMAND
Cut and Paste
One nice fancy feature of screen is the ability to "copy" text out of one window and "paste" it into another. To do this start the "copy" mode with <screen_escape_key>+<escape>. Now you can move around with the vi keys (most work, like hjklwb, etc) and probably the arrow keys work too. Go to the beginning of the text you want to copy and press enter. Now move around to the end of the text you want to copy and press enter again. The text is now stored.
Now switch to a different window and do a paste with <screen_escape_key>+] - yes, that’s a right bracket. Your text should come in as if you had just typed it. This feature seems quite overly complicated, but once you get used to it, it is actually quite useful and not really too difficult to use at all. In many cases I find it is quite efficient.
Recursion Of Screen Sessions
It is also possible to have screen sessions within screen sessions. This tends to happen when you’re using screen on a computer from which you log into another computer where you have a screen session. This works just like you’d think it would and is just as complicated as it sounds. It’s best to not do this if you can avoid it, but if you like this sort of thing, you basically need to "escape" the <screen_escape_key> so that it gets to the "inner" session. To do this use <screen_escape_key>+g which sends a screen escape sequence to the "inner" session. Then use one of the commands described above. Like I said, this gets complex and isn’t especially fun to use. But it can be done if needed.
Andrey’s Setup
This is Andrey’s method to get meaningful titles in screen sessions. I’m not sure I like the naming; it seems to put a PWD label on the status bar. I tend to like to see all my options. But I could see this style working for people who don’t do most things from their home directory (which I mostly do). There are some other nice ideas. The colors are very nice. Having the host always shown is less foolish than it may seem if you’re always using screen on remote machines. But I have it in PS1 so it’s redundant. But it’s not a bad concept since PS1 pollutes redundant stuff all over the screen.
escape ``
bindkey `^I other
bindkey `\' windowlist -b
hardstatus alwayslastline
# this works in modern screen
# hardstatus string '%{=b kg}%H%{w}%?%E%{R.}*%:.%?%n%=%h%=%{Y}%l
%{C}%d.%m.%y %0c'
hardstatus string '%{=b kg}%H%{w}.%n%=%h%=%{Y}%l %{C}%d.%m.%y %0c'
# for shift right and left arrows
bindkey ^[[1;2D prev
bindkey ^[[1;2C next
# for ctrl right and left arrows
bindkey ^[[1;5D prev
bindkey ^[[1;5C next
# for alt right and left arrows
bindkey ^[[1;3D prev
bindkey ^[[1;3C next
zombie d@
vbell off
defscrollback 100000
TITLEHOST=`hostname`
short_pwd () {
local HPWD="$PWD"
case $HPWD in
$HOME) HPWD="~";;
$HOME/*) HPWD="~${HPWD#$HOME}";;
esac
echo -n "${HPWD}"
}
case $TERM in
*term)
set_window_title () {
# hardstatus
printf '\033]0;%s@%s:%s\007\e\\' ${USER} ${TITLEHOST} "`short_pwd`"
}
PROMPT_COMMAND='set_window_title';;
screen)
set_window_title () {
SPWD="`short_pwd`"
# title
printf '\ek%s@%s:%s\e\\' ${USER} ${TITLEHOST} "${SPWD}"
# hardstatus
printf '\033]0;%s@%s:%s\007\e\\' ${USER} ${TITLEHOST} "${SPWD}"
}
PROMPT_COMMAND='set_window_title';;
esac
Problems With Screen
Sometimes upgrading while having an active screen session open will cut off the previous sessions. This problem is described nicely with solution here:
Basically you have to downgrade and then rescue your sessions, then upgrade again. Very annoying.
tmux
If for some reason, you don’t love screen, maybe you’ll find what you
need with tmux. At the very least, this
competing program has a much, much better name. There are some other
subtle improvements over screen (when I tried it I was focused on
vertical screen splitting) but overall, it’s a very similar kind of
tool. Definitely worth checking out if you’re interested in this kind
of thing. Many very smart people I know made the switch from screen to
tmux. Here are some reasons to consider tmux
.
-
The name of "screen" is unforgivable. It is understandable given that Screen was first created in 1987 before any internet searching confusion, but today, that’s an absolute bullet in the head.
-
The default key binding of GNU Screen is ridiculous. [ctrl+a] is well established in Emacs, and therefore the readline library, and therefore Bash and most shells, as: jump to the beginning of the line. If you’re a GUI person, it’s no better with [ctrl+a] being: select all. Again, life was different in 1987 but, then again, life was different.
-
GNU Screen has started not working properly with Vim using my escape key of [ctrl+g]. On startup, Vim produces some kind of something that Screen picks up as user key presses. I suspect it’s a Vim (8.2) bug actually but
tmux
does not have this problem. -
I was able to much easier get a much better status line with
tmux
that included a useful clock that I liked. -
In the past
tmux
led the way with vertical splits. I’ve lived without them so long (and Vim windows covers the deficiency usually) that I don’t even use them now thatscreen
has this feature. -
In general
tmux
configuration syntax is much saner. Again I suspect a lack of clarity on good standards did not exist when Screen started. Or maybe the non-English provenance is at play. -
I’m not sure if Screen has multiple paste buffers, but tmux seems to (e.g. list them with [ctrl+g,#]).
-
Clear your
tmux
terminal to a handy clock with [ctrl+g,t].
Important Usage Details
To restore a detached tmux session: tmux attach
.
Sometimes the size is messed up because it is still attached elsewhere. Use [ctrl+g,shift+d] to get a list of ones to detach.
To rename labels it is [ctrl+g,comma].
To monitor activity is simply [ctrl+g,:] set monitor-activity
To use copy and paste is very similar to GNU Screen but there are some
tiny changes that are probably for the better. To enter "copy mode"
use [ctrl+g,[] instead of Screen’s [ctrl+g,esc]; I think this
makes a lot more sense really even though I’m used to screen. In
Screen you move around with most regular vi keys working fine and when
you get to the start of the selection you press [enter]. With tmux
the start of the selection is signaled with [space] and the other
end of the selection, like Screen, is also with [enter]. I guess
that’s to help you make sure you don’t get your starting and ending
intentions mixed up and is probably a good idea.
Using [ctrl+g] and then a number will take you to that number screen; but what if you want to go to 10 or 11 or something? There are two ways, both very good. First, [ctrl+g,'] and then a double digit number will do exactly what you need. But also [ctrl+g,w] will give you a pretty decent interactivish thing to select your window from — vi keys even work! Nice!
It looks like tmux stores multiple copy buffers (how many?) and they seem to be in a stack so FILO rules. Delete top of the stack with
Most things should be similar to screen. Where different, consult the "KEY
BINDINGS" section of man tmux
.
Splitting Windows
I don’t go crazy with this but I often want to see some htop
while a
heavy remote thing churns away. So here are some simple window
splitting tips. First note that they’re called panes in the man page.
-
[tmux_escape,"_] - Horizontal split. Too bad it’s not = but that’s some strange thing related to buffers.
-
[tmux_escape,%_] - Vertical split.
-
[tmux_escape,arrows_] - Focus pane in that direction.
-
[tmux_escape,ctrl+o_] - Rotate panes.
-
[tmux_escape,{_] - Swap panes.
}
is the other direction if more than two. -
[tmux_escape,ctrl+arrows_] - Resize the panes.
-
[tmux_escape,alt+arrows_] - Resize the panes in bigger jumps.
-
[tmux_escape,x_] - Kill current pane.
-
[tmux_escape,q_] - Show pane index.
-
[tmux_escape,;_] - Focus previously active pane.
Sharing
To share a session is pretty simple (using the same login account). Basically with one tmux session running have the other person/location do this.
tmux attach-session
tmux attach # Should be the same.
tmux at # Should be the same.
There will now be two cloned displays and interfaces for the session.
You can use the -r
option to make the attach read-only so the second
system doesn’t cause any accidental trouble.
Tmux Configuration
The configuration is done from a file called by default
~/.tmux.conf
, a bit of an awkward name but ok. Here is a nice
description of how to use tmux
for people used to screen. Here’s a decent ~/.tmux.conf
based on
that.
# Chris' Tmux Configuration
# =========================
# Taken mostly from: https://mutelight.org/practical-tmux
# Hopefully this changes the hot key from the default of Ctrl-b to Ctrl-g.
set-option -g prefix C-g
# Make double hitting the hot key do what it does in screen.
bind-key C-g last-window
# Allows for sending commands to nested sessions like screen.
bind-key g send-prefix
# Numbering starts at 1 like the keyboard.
set -g base-index 1
# Eliminate any annoying polling for escape sequences.
set -s escape-time 0
# Hopefully this will help borking after modifying window sizes in a program.
setw -g aggressive-resize on
# Highlight active window.
set-window-option -g window-status-current-bg red
# Set clock mode.
#clock-mode
set -g clock-mode-style 24
# Make space go to the next window. Default is to do "next-layout".
bind-key * next-layout
bind-key Space next-window
# Suppress default of autonaming windows to running processes.
# Use "," to assign your own permanent names.
set-option -g allow-rename off
# Set status bar
set -g status-interval 1
set -g status-bg black
set -g status-fg white
set -g status-left "#(id -un)->"
set -g status-right "%d%b %H:%M:%S%Z #(date -u +%%H%%MU)"
# split panes using | and -
#bind | split-window -h
#bind - split-window -v
#unbind '"'
#unbind %
# Reload config file. Handy for experimenting with it.
bind r source-file ~/.tmux.conf
Other Interesting Software
Mosh
This appears to be an interface for the SSH client focused on interactive use. Its main feature appears to be high latency connections where it will show you what you’ve typed and not necessarily wait for the screen echo that sometimes causes poor SSH connections to produce a "typing blind" effect. Mosh’s Wikipedia entry and official web site.
Byobu
This is a program that provides extra features to programs like screen or tmux. It provides better notifications. Byobu’s Wikipedia entry and official web site.
Xpra
Need screen-like features for graphical things? Xpra is advertised as a "screen for X".