Screen and tmux

From Helpful
Revision as of 14:11, 19 April 2017 by Helpful (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Shell, admin, and both:

Shell - command line and bash notes · shell login - profiles and scripts ·· find and xargs and parallel · screen and tmux
Linux admin - disk and filesystem · users and permissions · Debugging · security enhanced linux · health and statistics · kernel modules · YP notes · unsorted and muck
Logging and graphing - Logging · RRDtool and munin notes
Network admin - Firewalling and other packet stuff ·


Remote desktops
VNC notes
XDMCP notes



Note: For something similar for X11, see xpra

tl;dr

Learn by doing:

  • Log into a remote host (ssh, putty)
  • Run
    tmux
    , or
    screen
  • You are now again at a terminal.
Do stuff with it.
  • Close the terminal window (to simulate a broken network connection)
  • Connect to the remote host again and run
    tmux att
    or
    screen -rd
    (whichever you were using)
Notice you are now looking at the same interactive terminal you had before the disconnect


Of these two programs,

screen is the better known and more likely to be installed. It's a fairly stagnated project now, though.
tmux is more actively developed, so has a few more features.

More detailed intro

Screen and tmux distinguish themselves from a regular shell in a few significant ways.


Overly detailed, yes :)
Shows the variation where you log in remotely, and use tmux/screen.
This helps explain why contained processes don't even notice that you go away.
A version without screen/tmux would have running processes and their terminal I/O tied directly to your shell process. With tmux, both are only ever connected to the background process.


They run processes separately from the shell you logged in with, meaning the program you started won't quit when you exit the shell / disconnect.

(For contrast: in typical shells processes you start are direct children of the shell proces, and the whole tree of processes gets cleaned up at once).
You can think of screen/tmux as a background service that hosts interactive shells.
Starting screen/tmux creates that host process, plus an interactive viewer into it.
Programs you start within screen/tmux will have their interaction (keyboard and output) wired to that host process. It is relayed to the viewer when it is connected.
When the viewer stops (e.g. shell closed, connection broken), it only stops the viewer, and the host and its contained processes are not affected.
You can re-connect the viewer at any later time, and continue to interact with the shell/program.
This is useful for anyone who who runs long-term jobs, wants to leave work around, has an iffy internet connection, troublesome WiFi, wants to leave (text-mode) editors open to continue with tomorrow, or whatnot.
(It's also nicer form of backgrounding than using & and nohup, though that can work fine for non-interactive programs)
(For comparison: nohup means that when the parent of a nohup'd process dies, it becomes a child of init. This is the easy workaround until you care about interactivity.)


Terminal multiplexing - a feature they added because, well, it's useful.

It means one hosted session can contain many interactive shells side by side
analogous to a tabbed web browser. Switching between them mainly just connects the keyboard/output to specific things.

tmux

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

For newcomers, you are probably most interested in:

  • starting a new session
    tmux
    (or tmux new)
  • creating new windows: Prefix-c
  • disconnecting from a session: Prefix-d
  • reconnecting to a session:
    tmux att

Closing/removing a window is often done by exiting the shell. (If something is hung in it, you can kill the window explicitly)


Prefix is Ctrlb by default, but you may want to change it to Ctrla to avoid confusion when you're on a host that only has screen. Because that will happen. (For the same reason, I like to rebind keys so that overlapping features have the same keys. See the example config below.)


Tmux when compared to screen

From those who know screen, it's basically the same, but tmux...

  • has different key shortcuts (but many people like to remap them. See below)
My switch from screen to tmux went surprisingly smoothly once I rebound keys to imitate screen  :)
  • is a more active project, so more likely to have or get features you want
  • is less bother when you use X forwarding
in new windows it updates DISPLAY according to the outside environment of the most recent attach (verify)
  • models split windows a bit better.
more flexible layout-wise, and the split and layout are remembered between sessions
  • is scriptable
  • can be made to automatically rename windows according to what they are running
  • is a little more modular. A window can be attached to and moved between multiple sessions

Terminology

You, as a client, connect to a session (more than one client can connect to a session).

Multiple sessions can be useful, say, to split work and home use.

Within a client/session you look at one window at a time (named, fixed numbering, often switched to by index).

Windows can be split into panes if you think that useful (numbered by current position, can be cycled through).

Maybe you'll prefer putting distinct tasks into distinct windows (e.g. IRC, different coding projects), and put related bits of the one task in panes (e.g. editing code, running it, viewing the log).


Interaction I use most

There are plenty of cheat sheets out therem.
The way I use it most of the time:


The Prefix is Ctrl-b by default, but most people (apparently including the tmux devs) seem to remap it to Ctrl-a. (For the remapping mentioned here, see the config file example somewhere below)


starting, attaching, detaching

  • tmux
    , or
    tmux new
    starts a new session
  • tmux attach
    attach - if you have just one, you don't have to worry about the details
By default it will leave other connected clients attached (and use the smallest window size of the set, padding the rest). If you want it to detach other clients after attaching, the easiest way is probably
tmux att -d
  • tmux ls
    - list sessions
  • Prefix-d Detach the current client (same as in screen)


scrollback

  • Prefix-[ - start navigating in tmux scrollback for the pane
There's also searching and copying, but I haven't use it


window

  • Prefix-c Create a new window (same as in screen)
  • Prefix-0 through Prefix-9 Move to window by number (same as in screen. I like to configure tmux so that 1 is the first window, not 0)
  • Prefix-w List windows (I like to remap this to Prefix-")
  • Prefix-l Move to the previously selected window (same as in screen. I like to add Prefix-Prefix to do the same)
  • Prefix-& Kill the current window (I like to remap this to Prefix-K)
  • Prefix-, Rename the current window (I like to remap this to Prefix-A)


Pane

  • Prefix-% Split into two panes, vertically. (I like to remap this to Prefix-| )
  • Prefix-" Split into two panes, horizontally (I like to remap this to Prefix-- )
  • Prefix-x Kill current pane (...but I typically just log out of its shell)
  • Navigate
    • I don't like the standard way (that I've seen)
    • I like to map Prefix-arrowkeys to do this (and only ever use that)
  • Relayout:
    • Prefix-space use next layout (easier), OR
    • Prefix-Alt-1 through Prefix-Alt-5 to use specific layouts. When I actually care to relayout, I seem to use 5 most.
  • Resize
    • I like to map Prefix-Alt-arrowkeys to do this


Session

  • Prefix-s - list sessions
  • Prefix-( - switch to user's previous session
  • Prefix-) - switch to user's next session


Misc

  • Prefix-? List all key bindings (same as in screen)


on tmux's copy mode

More on panes and windows

Example config (~/.tmux.conf)

Note: Tmux 1.7 added a bunch of interesting settings, but using this config in earlier versions will cause complaints. (only later versions report their version (-V ?), so you may have to look at your package management to see which version you have installed)


# Note on binding:
#   bind is the same as bind-key
#   -r means 'repeatable without repeating the prefix'
#   -n means 'does not need prefix'
#
# setw (and set -w) is short for set-window-option, and is window-specific
# set -g  means 'set globally',
# set -u  un-sets,
# set -a  appends to a current value (for strings)
 
 
# quick reload of this config into the current tmux (useful while fiddling with it)
bind r source-file ~/.tmux.conf
 
# start numbering at 1, which eases window switch by number (C-a 1, C-a 2)
set -g base-index 1      
set -g status-utf8 on
# History in amount of lines. Infinite is also possible, but I would not recommended it
#    as I once found a tmux with top in it that had allocated 12GB of RAM
set -g history-limit 10000
 
#set -g mouse-select-pane on  # switch to pane via mouse. Usually can't hurt
#set -g mode-mouse on  # adds scrollwheel scrolling (and a few other things)
#                             # ...but messes with middle-button pastes?
 
# set graphical-terminal title
set -g set-titles on
# I like to identify my mess of xterms by the current command
#   and don't care about window numbers and such, so I use:
set -g set-titles-string   '#W#F             #T'
 
 
# add or remap horizontal and vertical pane split to  -  and  |  
# (easier to remember) 
# You can leave the old ones, but I like " as window choosing (like screen)
unbind %
bind-key | splitw -h
unbind '"'
bind-key _ splitw -v
bind-key - splitw -v
 
 
# Pane navigation (I haven't settled on one yet)
 
# Both navigating and resizing panes is useful. 
# using arrow-key combinations for both is easy for me to remember
# I'll navigate more than resize, so I put the latter under is under Shift-arrows
bind-key -r Left select-pane -L
bind-key -r Right select-pane -R
bind-key -r Down select-pane -D
bind-key -r Up select-pane -U
bind-key -r S-Left resize-pane -L 2
bind-key -r S-Right resize-pane -R 2
bind-key -r S-Down resize-pane -D 2
bind-key -r S-Up resize-pane -U 2
# see also repeat-time (we stay in )
 
# how long to show pane numbers (C-a q). 
# Default is too fast to scan the screen.
# I don't use this much.
set display-panes-time 2000  # (which is 2sec) 
 
# Cycle through windows, or panes.   I prefer using it for panes
#  (The way I use it, C-a C-a is good for most of my window switching needs)
bind -n f12 select-pane -t :.+
#bind -n f12 next-window
 
 
 
# Set screen-like shortcuts  (also to avoid Ctrl-b for vi users)
unbind C-b
set -g prefix C-a
unbind ^a
bind-key ^a  last-window            # C-a C-a: quick switch to last-viewed window
                    # note: you may instead like this to do send-prefix
                    #   so that you can easily send commands to an inner/remote tmux.
bind-key ^i  select-pane -t :.+     # C-a C-i: cycle between panes in window
bind-key A   command-prompt "rename-window '%%'"         
bind-key '"' choose-window     
bind-key k   confirm-before -p "kill-pane #W? (y/n)" kill-pane
bind-key K   confirm-before -p "kill-window #W? (y/n)" kill-window  
 
 
# Joining windows into panes. (will relayout if the thing being moved is already paned)
# taken from http://unix.stackexchange.com/questions/14300/tmux-move-window-to-pane
bind-key j command-prompt -p "join pane from:"  "join-pane -s '%%'"
bind-key s command-prompt -p "send pane to:"  "join-pane -t '%%'"
# You may also want to know about break-pane, 
#         and remember relayouting via Prefix Meta-[0-5]
 
 
### Style
# puts user@hostname on the left of the window list (in a subtler color)
# clearer (color-based) marker of the active window in that list
# clearer current-pane contrast/coloring
set -g status-bg green
set -g status-fg black
set -g status-left-bg green
set -g status-left-fg white
set -g status-left-length 30 # allow more length, for longer hostnames
set -g status-left '#T  '
set -g window-status-current-bg black
set -g window-status-current-fg white
set -g status-right-fg black
set -g status-right-bg green
set -g status-right '%H:%M, %a %h %e '


Special values in titles include:

Character pair    Replaced with
#(shell-command)  First line of the command's output
#[attributes]     Colour or attribute change
#H                local hostname
#F                Current window flag                     
#I                Current window index                    
#P                Current pane index                      
#S                Session name
#T                Current window title (a shell thing? typically user@host:path ?)    
#W                Current window name  (tmux's own, the one shown in the bottom bar)
##                A literal ‘#’

You can also use strftime variables. Keep in mind those start with a percent sign instead.

The color/attribute changes look like:

#[nobright fg=green]

When doing complex things, it may help to know that #[] is interpreted after all other # sequences.



See also:

Color based on host

To lessen possible confusion of which host you're on

See e.g. the solutions at http://unix.stackexchange.com/questions/122508/set-tmux-status-line-color-based-on-hostname

Semi-sorted

Environment

Screen

The manual calls screen "a full-screen window manager that multiplexes a physical terminal between several processes (typically interactive shells)."


Usage basics

Windows

The distinct things within an instantiation of screen are called windows.

By default, each window starts with your default shell, so each window is useful for a distinct task, say, running and editor, running a program, viewing logs.

Window-related commands you may well use:

  • Creating a new one: Ctrl-a c
  • You can switch to a window by its number Ctrl-a number
  • You can toggle to/from the last used window with Ctrl-a Ctrl-a
  • You can get a list of windows with Ctrl-a "


You may like to have an on-screen list of windows. See configuration notes below (or look to byobu).


Instantiations of screen

starting, stopping
To start a screen, type
screen
. This starts a new screen process and creates a single window inside it, with a shell according to your user settings.

Most commands are Ctrl-a followed by something. For example, help is Ctrl-a, h

The usual way to stop a screen by stopping the processes from its last window (or, if you can't easily stop the contained process, kill that window - Ctrl-a, k).


Detach, reattach

You detach (disconnect) from a running screen instantiation with Ctrl-a, d.


Reattaching comes in quite a few flavours, though out of habit you'll probably remember just one or two convenient ones.

  • screen -list
    shows all the running screens for the current user. Makes sense when you run more than one.
  • reconnect commands can often be used with or without argument.
    • without tends to mean:
      • "If there is exactly one screen process, reconnect to it"
      • "If there are more, show a list"
    • with tends to mean "reconnect when there is one unique string-starting match"
      • For example, if you have 18720.pts-0.hostnm and 23972.pts-0.hostnm, then
        screen -r 23972
        but also
        screen -r 23
        will connect to the second.

If you don't want names like 5730.pts-0.hostnm, you can specify your own with -S


As to the different reconnect commands: (verify) (this needs clarification / double-checking)

  • -r
    for 'resume'. Won't connect to an already-attached screen (and won't create a screen)
  • -R
    - largely like like -r, but if no screen exists (or it is attached and there is no request to detach it), it will create one
  • -RR
    - basically "connect to the first (detached) screen you can find; if one isn't running, start a new screen."
  • -d
    - when connecting to a currently attached screen, this will disconnect the others first
  • -D
    - like -d, plus it causes logout from the shell the other connection came from.
    • Usually means your other remote login (terminal/emulator) will be closed or logged out, which is nice for peace of mind.
  • -x
    , which means 'join an attached screen without detaching others'
    • This means sharing both input and output, without any choice. You may want multiuser mode instead
    • (the smallest window size between the logins will be used)


These can be combined. There's more than a dozen combinations

  • -rd roughly means "connect to the last one and detach others"
  • -RD roughly means "-rd, detach+logout if it was attached, create it if necessary" - possibly the easiest do-what-I-want

Some more key commands

The key shortcuts I consider useful are:

  • Window stuff:
    • Ctrl-a 1 switches to window by number, 1 though 9.
    • Ctrl-a Ctrl-a switches between last activated windows
    • Ctrl-a " gives list of windows, also allows switching with arrows and enter
    • Ctrl-a c creates new window (removing one can be done with a logout, or:)
    • Ctrl-a K removes (kills) current window (useful for things you can't Ctrl-C)
  • Split screen:
    • Ctrl-a S (capital S) splits screen top-bottom
    • Ctrl-a | (pipe) splits screen left-right
    • Ctrl-a Ctrl-i switches to next part of split screen
    • Ctrl-a - makes current part of split screen smaller
    • Ctrl-a + (on US keyboards meaning Ctrl-a Shift-=) makes current part of split screen larger
  • Other:
    • Ctrl-a ? displays various keyboard commands
    • Ctrl-a d disconnects


Scrollback

Copy mode (which doubles as a scrollback viewer):

  • Use Ctrl-a [ to enter copy mode, Esc to exit.

In scrollback/copy mode, you can:

  • Navigate
    • vi-style line/column movement: h, j, k, l
    • page-based movement:
      • PgUp and PgDn often work
      • C-u, C-d: half page up, down
      • C-b, C-f: full page up, down
    • For more, see e.g. [1]
  • Search
    • using / (forward) and ? (backward)

Configuration

Line drawing and/or Unicode

Screen picks up on locale settings and should just work. If it doesn't, it usually means the locale settings do not handle what you want, or your terminal program is using some different interpretation.


Assuming you want to use UTF8 (and unless you specifically must have something else, you want UTF8), you should generally check two things:

  • that (your account at) the server has an UTF-8 based locale (check whether LANG and/or LC_ALL(verify)) are set this way.
  • that the terminal program interprets the server correctly. For example, PuTTY defaults to 8859-1 and not UTF8.


If LANG nor LC_ALL does not mention utf8, you probably have to set up your system first; see Localization,_internationalization#Linux_locale_setting

Alternatively, you can also force UTF8 treatment throughout screen by starting screen with the -U option, but this isn't always ideal (it ignores the context of the system it runs in).


A bunch of configuration possibles

You can create ~/.screenrc to have some settings, for example:

# hide the 'this is screen' message that appears when you start 
startup_message off

# allow more scrollback than 100
defscrolback 2000


# If you are primarily using remote text logins, you probably don't want 
# X programs assuming they can use DISPLAY, so clear it:
unsetenv DISPLAY


# remove some Ctrl-A <key> bindings that you only really use by mistake, 
#  e.g. lock screen, hardcopy, write termcap, perhaps others
bind ^x
bind h
bind .


Caption and hardstatus

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)
# always show caption, not only when using split screen 
# (I like seeing that I'm using screen, and what host I'm on)
caption always
caption always "%H | %>%{kw}%?%-Lw%?%{wb}%n*%f %t%?(%u)%?%{kw}%?%+Lw%?%<"

The funky caption line is to show the list of all windows, with the current one highlighted -- because by default it will show only the current window number and name. Example result:
Simple-screen-window-bar.png

You can do much funkier things here - see for example byobu (formerly screen-profiles).



This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

Copied examples that show the window list:

# white bar, current window blue
caption always "%H | %>%{kw}%?%-Lw%?%{wb}%n*%f %t%?(%u)%?%{kw}%?%+Lw%?%<"

# transparent bar, current window inverse (subtler)
caption always "%>%{wk}%?%-Lw%?%{bw}%n*%f %t%?(%u)%?%{wk}%?%+Lw%?%<"



hardstatus

The hardstatus is a slightly more complex subject. It's roughly a separate string that can be updated via terminal control codes. Your terminal/emulator has to support it, as well as allow setting it.


You can tell various terminals and emulators (particularly graphical ones, e.g. PuTTY, the regular ones in *nices,) to show it. For example, you can alter your termcap with something like:

# advertize hardstatus support to terminal 
#   and use escapes to put it in the window title
termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]2;\007'
termcapinfo rxvt  'hs:ts=\E]2;:fs=\007:ds=\E]2;\007'

This can be handy when screen opts to set the title to just 'screen'


You can tell what screen should do when hardstatus support is not advertised (via termcap), one of:

hardstatus ignore       # if not supported by terminal, don't show
hardstatus lastline     # reserve last line in terminal
hardstatus message      # use whatever screen's message mechanism currently is
Prepending
always
to any of these (alwaysignore, alwayslastline, alwaysmessage) will force the option even if the terminal supports hardstatus. Just always seems to be shorthand for the always variant of the default (lastline?).


You can tell screen to set particular things in the hardstatus. For example:

# basic message to the hardstatus
hardstatus on            # if off, hardstatus messages are printed on screen (verify)
hardstatus string "%H [%n%?: %t%?] %h"  


The hardstatus string line tells screen how to use the hardsatus.

%h refers to the stored hardstatus (settable via
"ESC]0;<string>^G"
or
"ESC_<string>ESC\"
)

Titles for screen's own windows

While you can set these manually (Ctrl-A Shift-A).

You can also set them via escapes, but the most convenient way for that to work is automatically.

If you want to also show things like the current directory, the place you probably want to send those escapes from is the prompt string.

See e.g.


Warnings

"Attaching from inside of screen?"

Note that if you see "Attaching from inside of screen?", you probably did a screen -rd (or so) from within screen.

It says this in the screen you tried to do it from - so if you did a -rd or such, you'll only see it once you return to the screen. (which may be hard to see unless you use a caption-like thing to help you see when you're in a screen session)


In the case where you (implicitly or explicitly) referred to the screen you were in, in which case the net effect is that you will be disconnected (you'll see [remote detached]), and you will see the "Attaching from inside of screen?" message once you (re)connect to that screen.



Semi-sorted

Flow control

Particularly emacs users might accidentally trigger flow control, since Ctrl-S is stop (Ctrl-Q is continue).

Can be enabled/disabled with Ctrl-a f. If that solves your problem, you can disable it for all new sessions via screen config:
flow off
and/or
defflow off


screen and X tunneling

Screen will mess with SSH tunneling of X.

Once you reconnect to screen it will contain the DISPLAY inherited from the shell you started screen from, which will likely result in a:

cannot open display


The SSH client did set the new X tunnel in the connecting shell's DISPLAY, of course, so you'll have to update it manually. Basically:

# after connecting to the host, before reconnecting to screen, find the new SSH connection's DISPLAY value:
user@host:~ $ echo $DISPLAY
localhost:12.0

# connect to the screen and in the relevant shell(s) do something like:
export DISPLAY="localhost:12.0"


TODO:

  • figure out whether there is any more automated way to do this.
  • tmux will try to do this automatically

"Cannot open your terminal ‘/dev/pts/x’ – please check."

Probably means you used
su
to change users.


The problem is that the permissions on that pseudoterminal do not allow you (even if you're root(verify)).

An
ls -l /dev/pts
will probably show something like:
crw--w---- 1 myusername tty 136, 6 Apr 12 13:16 /dev/pts/6


To work around this, you can do:

chmod a+rw /dev/pts/6

It's insecure, but useful enough for, say, an admin checking up on screens before rebooting.



If you su'd to a user you want to actively use for a while, you may like workarounds:

See also

  • the man page (an online version here)
  • the user manual (like here).