People occasionally ask me why
tmux is significantly better than
screen, and I end up mumbling the first few things that come to mind. This has yet to sway anyone. Here, then, are some things that I enjoy about using
First, some terminology, so the rest of this makes any sense at all.
screen, if you were not aware, are multiplexers—they let you run multiple terminals (or terminal programs) at the same time, switch between them, and disconnect or close your terminal without killing everything you were running. If you didn’t know this then you should probably stop now and poke around tmux’s site or something.
- A session is a particular group of terminals owned by
screen). When you run
tmuxbare, you get a new session.
- A window is a numbered terminal inside a session.
- A pane is each compartment within a split window. (I lied above; a window might actually have several panes and thus several terminals. But a window is identified by one number.)
- An xterm is a single GUI terminal window (or tab). You may be using another terminal emulator, or you may be in a non-GUI virtual terminal; I’m using “xterm” as an umbrella term for all of these.
I’m also assuming that
^A is your multiplexer trigger key, although
tmux defaults to the more awkward
.screenrc, fiddled by hand over the course of many months after I started using
1 2 3 4 5 6 7 8 9
What the fuck is any of this? The only real configuration here is the first line, which sets a fairly simple status bar. The rest is unreadable sludge picked off of Google to make terminals inside
screen work the same way as terminals outside it. I see this as a serious failing in the one core feature that defines a multiplexer: being invisible.
Some of this might not be necessary any more; maybe termcaps have been improved in the meantime. Part of the very problem is that I can’t know; the best I can do is delete bits of it and see if
screen still behaves correctly, assuming I remember all the quirks I was trying to fix in the first place. It’s 2012. I shouldn’t ever see the word “termcap”.
tmux, which just worked. The only terminal-related fudging I ever had to do was set my
xterm-256color for it to respect 256-color sequences. Not entirely unreasonable.
tmux can also inherit parts of the environment when it’s detected a change; by default it looks for some common X and SSH stuff. The upshot of this is that your SSH agent continues to work across SSH connections; the new environment only applies to newly-created windows, but zero hacks are necessary.
By default as of
tmux 1.6 (I think), when you create a new window, it’ll get the same current working directory as the current window.
If you run
screen with no
.screenrc, you get what looks like a regular terminal—you can’t even easily tell that you’re in a multiplexer, save for any terminal-related weirdness.
If you run
tmux with no
.tmux.conf, you get a status bar listing all your windows, as well as the name of the session and a timestamp.
Sure, you can just paste a line you find on the Web (like mine above, even!) into your
.screenrc and fix this instantly. But look at that line: what if you want to change a color? Can you even tell which of those escapes is a color? I wrote the damn thing and I couldn’t tell you.
Here’s an excerpt of the status bar configuration from my
1 2 3 4 5 6
High xterm color names are not particularly friendly, and the actual contents of each part of the status bar are still controlled by special escapey codes. But you can tell what’s going on, and you can customize it yourself with relative ease. You can even change these settings from within
tmux itself and see the changes live.
How do you customize the xterm title in
screen? According to the FAQ:
1 2 3
Ah! it’s our old friend termcap, followed by line noise. The FAQ entry indicates that this doesn’t really set the xterm title, but uses an obscure terminal feature known as a hard status line, and tells
screen to update the hard status line by using the xterm escapes that actually change the xterm title.
Let’s compare to my take on this for
That gives you something like
[blog:3 perushian] source/_posts/2012-03-21-tmux-is-sweet-as-heck.markdown.
#W, meaning “window name”, uses the same special xterm escape sequence
screen invented to set the window name, so my
.zshrc spit out custom window titles that work under either multiplexer. (Though, strangely,
screen‘s own invention never worked for me very reliably in
screen could only split horizontally when I used it, but it appears it recently learned to split vertically as well. I can’t speak to how well this works; I never actually used its splits. It seems the only default keybinding for switching between panes is
^A " will split horizontally, and
^A % will split vertically. Your current pane is outlined in green.
^A arrow will move to the next pane in that direction.
^A ctrl-arrow will resize the current pane in that direction;
^A alt-arrow will resize five cells at a time.
You can tell
tmux to use a particular “layout”, which is a general approach it’ll use for determining sizes of panes.
^A alt-1 through 5 will rearrange all your panes (even the split direction) to fit one of the five builtin layouts. It’s great if you don’t care about the actual sizes of the panes, which I generally don’t 8)
If you attach to an existing session without detaching it, you’ll just attach to it twice. Both xterms will control the same session; it’ll have the same current window and pane, and changes to a pane will be reflected in both xterms. If a session is smaller than its containing xterm,
tmux will draw a border and a field of dots in the unused space.
It gets better!
tmux new-session -t <existing-session> will create a new session grouped with the one you name. They’ll share the same set of windows—close or create a window in either session, and you’ll see it in the other. But each session can have a different current window, so your two xterms can work on two things in one session at the same time.
For finer-grained control,
tmux link-window -s foo:1 -t bar:2 will create a new window at position
2 in the session named
bar. This window will control the same set of panes, with the same terminals and processes, as window
1 in the session named
tmux break-pane -t <pane> removes a pane from its window and sticks it into a new window.
tmux join-pane -t <pane> is the reverse operation: it splits the current window and uses an existing window as the new pane.
There are similar commands for rearranging panes and windows. Anywhere you refer to a pane or window, you can refer to a pane or window in an arbitrary session as well, so you can move whatever you want to wherever you want.
^A pgup enters copy mode and scrolls up a page, which is usually what I wanted anyway. In
screen, I always had to
^A esc to enter copy mode, then
pgup. (I didn’t know how to change the key combination timeout at the time, either, so sometimes I’d type too fast and that just wouldn’t work.)
tmux key bindings are just regular commands. Anything you can do with a keybinding, you can do from
tmux‘s command line, or from running
tmux <command> regularly from a terminal—either inside or outside
tmux. (A handful of commands only work from inside
tmux, but these are interactive commands that rely on
tmux having control over the terminal.) You can script pretty much anything with ease.
One caveat to
tmux: while every
screen session is its own process,
tmux invisibly runs a master server that handles every pane in every session owned by your user. This lets the stuff in the previous session work. The only real impact of this is that if the server crashes, all your sessions go down with it. Thankfully, this tends not to happen.
The manpage is excellent and thorough. Most anything you may want to do can probably be accomplished with an obviously-named option or command.
Some other stuff from my
.tmux.conf that you may find useful:
^A as the magic keybinding:
1 2 3
^A space to switch to the next window to the right,
^A ctrl-space to switch to the next window to the left, and
^A ^A to switch to the last-used window:
1 2 3
Set the esc/alt disambiguation timeout to 50ms. The default is half a second, which makes vim kind of painful.
Start numbering windows at 1, not 0. I like the leftmost window to be the leftmost number on my keyboard.
TERM=screen-256color in new windows. (
tmux doesn’t have its own
$TERM; it hijacks the
screen family, so whatever recognizes
screen should recognize
tmux to use xterm sequences for, e.g., ctrl-arrow. I don’t know why this isn’t on by default. If odd key combinations aren’t working for you, this is probably why.
Feel free to steal my color scheme, too. It’s simple, but a bit less glaring than the 70’s black-on-green that you get by default.
Now, go forth and multiplex! I am hilarious.