Hacker News new | past | comments | ask | show | jobs | submit login
A Quick and Easy Guide to Tmux (2015) (hamvocke.com)
176 points by mjirv on Oct 29, 2019 | hide | past | favorite | 84 comments



I used to enjoy Tmux, then noticed I didn't need its core persistence/session feature; I mostly used it for windowing & tiling, which are okay but come with lots of warts you need to avoid, and before you know it your tmux.conf is 150 lines of stuff copy-pastaed from StackOverflow and the Arch wiki, mouse & copying keep being janky, and you're in for long sessions of configuration whack-a-mole where each fix somewhere breaks something somewhere else. Also, the client/server architecture is great if you need it, but for everyday development I don't, so I'd rather avoid the extra layer.

Not blaming the authors/maintainers at all, they're responsive and Tmux is extremely reliable. But in the end, it feels like they're battling to implement features at the wrong layer, and UX suffers.

In the end, I realized I just wanted a good terminal emulator that is {fast, featureful, scriptable, keyboard-friendly}.

If that sounds familiar, give Kitty a try: https://sw.kovidgoyal.net/kitty/ (and run https://fishshell.com/ in it, but that's another discussion :)


Whereas I use it primarily for the persistence layer, since I'm often sshing on a flaky connection and it's nice to be able to leave things open and be able to come back to them, or to attach to a session I left open on my desktop when I'm away.

Tabbing/windowing is a nice bonus; I don't use tiling in tmux all that much, since as you said, it can be done on a different layer, but it is occasionally useful.

My biggest frustration is that there are like ten million places where you need to tweak options to have it behave like a normal shell (scrolling, selection, etc.). It would be nice if these were less quirky by default.


Recently I switched from Tmux to Kitty, and couple of days ago I realized that I really miss Tmux’s persistence. It’s just so easy to lose a session!

When GUI hangs or crashes (which happens with Kitty sometimes) I really want to be able to start it again and get the same session back. Especially considering that there’s no way to update configuration of running instance and that it loses its remote control socket if you launch another instance on the same socket by accident, hurdles like these can be profoundly inconvenient when you're in the middle of work.

That said, Kitty is really fast and decently scriptable (though perhaps not as flexible and definitely less straightforward than Tmux, primarily due to lack of consistency—some commands are remote-control only, others are internal-only), and with turned off window decorations it can look fantastic and offer all of the screen estate without the inconveniences of native macOS full-screen mode I had to use with Terminal.


Interesting because I'm using it mostly as a windowing/tiling use case. I liked it better than using multiple windows/frames in say Emacs, and I didn't like learning new window/pane splits using iTerm2 (OS X).

But you're super right, I have so many little "quirky" things that just don't work right, like I used to be able to easily double click a line and it would just copy it to a buffer; pasting from my host OS requires different key bindings, and my TMUX config file has slowly grown as I tried to get it working just right... Might be time for me to learn iTerm2 properly....(maybe I can modify keyboard shortcuts to be like Tmux for moving around to different panes....) But part of me worries about the time when I have to go back to a remote dev env where I'm expected to SSH to a protected source code machine.


I’m curious, can you share what industries this practice is common, sshing into a protected source code machine?


I worked in Security for a bit (that was actually a case of RDPing to a dev environment) and some friends at certain projects at big tech were telling me about their setups and how they had to learn Emacs again because all the code and their dev workstations were in a protected remote environment and no source code was allowed on their local machines.


In embedded, I did a _lot_ of development work _on_ the physical target hardware via SSH. It wasn't every product, but it was most. It wasn't from the beginning, but rather there was always some point in development time where the feedback loop would tighten up dramatically if the work was being done on a device on the bench.


Not the parent poster but for some financial services companies (bank, insurance), I have heard of development being done on a remote desktop, sometimes without direct ssh access.


http://www.brain-dump.org/projects/dvtm/ lets you have the windowing / tiling stuff without the session detaching.

some people combine https://wiki.archlinux.org/index.php/Dtach and dvtm in whatever combination they want to get screen/tmux without the giant codebases (I love screen, but I don't love that it still has code in it to connect to serial terminals)


Heh, connecting to serial terminals is the only reason I even have screen installed nowadays.

I wish there were a port of cu to Linux, but I haven't come across one yet.


> I mostly used it for windowing & tiling [...] it feels like they're battling to implement features at the wrong layer [...] In the end, I realized I just wanted a good terminal emulator

If you just wanted the windowing and tiling, wouldn't a tiling window manager be better? It's kind of weird that you concluded the right layer for window tiling was the terminal emulator.

Personally, I only use the window tiling features of tmux when I'm not already working inside a window manager (like when I'm on a /dev/tty*).


> If you just wanted the windowing and tiling, wouldn't a tiling window manager be better? It's kind of weird that you concluded the right layer for window tiling was the terminal emulator.

I tried a tiling window manager (not sure which) a long time ago and didn't like it, it felt too heavy-handed and unnatural to me. My daily driver is:

- GNOME Shell ...

- ... with the occasional Super+{Left/Right} for basic half-screen splits (e.g. term on the left and editor on the right)...

- ... and I use a little helper script ( https://github.com/ronjouch/marathon ) to run-or-focus apps.

With these three things, I meet my "simple tiling" needs and keep the flexibility I like from non-tiling WMs.

But Sway looks cool, I'll definitely try it one of these days :) , maybe I'll change my mind.


Maybe they didn't want tiling for the rest of the windows? Or maybe they use something other than Linux/BSD and can't run a diff window manager.


Holy hell, has the options changed between different versions of tmux. Getting a consistent version across multiple version is near impossible.


I used Fish for years and eventually switched back to Bash and then to Zsh because I couldn't really deal with all the differences in the two, and the lack of customization in Fish. I'm interested in giving it another shot, but I'd really like to know what you like about it in the first place.


I like Fish because I find it has sane defaults, i.e. {coloring, autosuggestions, completions} all work well out of the box with zero or little configuration.

You can replicate a fish-like feeling in zsh (coloring, completions, etc), but for that you need a plugin manager, a million bajillion finicky plugins, and then configuration/performance hell [1] happens. I tried that, got bored of it, then learned to fish and never looked back at zsh.

That being said, out of the interactive shell I don't like the exoticism of fish as a scripting language; I keep preferring shebanged, shellchecked [2], defensive [3] (ba)sh scripts, they're a stable and portable evil I know.

Also, I'm curious what makes you feel "lack of customization in Fish": what can you customize in Zsh that you cannot in Fish?

[1] https://github.com/zsh-users/zsh-autosuggestions/issues/29 , https://github.com/zsh-users/zsh-autosuggestions/issues/22 , https://github.com/robbyrussell/oh-my-zsh/issues/5569 , https://github.com/zsh-users/zsh-autosuggestions/issues/102 , https://github.com/robbyrussell/oh-my-zsh/issues/6338 . And yeah okay, most of these issues are about one specific plugin, and oh-my-zsh, which is known to be a terrible kitchen sink. Fair. But even then, I prefer fish's "batteries included" (and tested) approach to having to the alternative of doing all the mixing myself and dealing with weird plugins interactions :).

[2] https://github.com/koalaman/shellcheck

[3] https://jvns.ca/blog/2017/03/26/bash-quirks/


> sudo apt-get install tmux (Ubuntu and derivatives)

I believe you just insulted the entire Debian community.

Jokes aside, tmux reminds me of emacs (similar esthetics & key bindings), the same way screen reminds me of vim (how do I get out of this thing?)


They both have both types of keybindings.


'pkill screen' should do it.


Having being a `screen` user for over two decades, migrating to tmux has been a pain. A week ago, however I discovered a wrapper called `byobu` (1) which really helps, and controls both screen and tmux depending on which one you have on your system. It basically wraps Function keys and more to tmux, but has plenty of other features. Time will tell if it was worth installing, but I do believe it's simpler for me to use it as a transition from screen.

(1) https://byobu.org


I've been a screen user for decades as well, and don't feel compelled to use tmux (and also tmux has one too many concepts for me, I don't need sessions). Did you find some compelling reason to switch?


Screen has sessions too... unless I’m missing something and this means something else


zoom pane is reason enough to me.


byobu certainly looks good, and I'd recommend it to any new user. Having spent a while to learn all the shortcuts of tmux and customizing my env with tpm plugins, there's low value in me re-learning a new set of shortcuts.

I also wonder how byobu users can use their system-defined Function keys while using byobu, since it seems to have set shortcuts on all these keys.


While on the subject, I'd like to share a solution I came up with for nested sessions:

https://github.com/xelxebar/tmux-addons/tree/master/nesting

Essentially, it defines some keys that let you "focus" on a particular nesting level. I've had some instances of needing four levels of nesting and found this to be quite nice.

The configuration is a tad idiosyncratic due to the way tmux handles variables, but it should be pretty well document in the readme.

Hopefully, someone else finds it useful. I've had to deal with sessions four levels deep and found this relatively ergonomic.


Holy cow tmux has changed my life.

No longer do I have to worry about losing all of my process when I accidentally close iTerm. This, coupled with the fact that you can Ctrl-B Ctrl-B and control your tmux within tmux... It's even fairly easy to script and make awesome workflows. Take for instance this script which shows a diff in a left pane and a commit editor in the right pane: https://gist.github.com/nvahalik/36108d4b892b6f66982537235f9...


I am sure you may know this already but iTerm has a prefenrece setting called "Confirm Quit iTerm2 ... command"

Checking it on has saved me quite a bit of trouble.


Yes. But even with that, I've accidentally killed it before via Activity Monitor... still a great tip, though.


I usually run screen within tmux if I need nested virtual terminals.


I spent a while trying to file down some of the rough edges around different versions of tmux and compatibility with shells / colors / vim / scrolling / weird keycodes / etc. and have some commented dotfiles here:

https://github.com/ohazi/dotfiles

It still has warts, but hopefully this is a useful reference to someone... I still haven't found a single source that covers all of these things well. Tmux config is surprisingly unintuitive.


> Tmux config is surprisingly unintuitive.

And sometimes you get some stray tmux process running in the background that somehow blocks it from updating the configuration until you find and kill every running tmux process. Really annoying.


Isn't that a simple matter of

  ps aux | grep tmux
  kill -9 12345

?


Yes, that is simple. Finding out the first time why it suddenly stopped updating the config - after it already worked multiple times minutes before that - is a different matter.


I prefer the nuclear option, which also gives you a bit of a gamble depending on your search string

    pgrep tmux | xargs kill -9


`pkill -9 tmux` (or `pkill -9 [t]mux` if you're doing it over ssh)


>>> I’ll proceed to give them a two minute tour about what you can do with tmux. After that they’re either hooked and want to try it themselves or they tell me to go away with my ancient neckbeard tools and just use iTerm2.

FYI, iTerm2 actually has a tmux integration. Allows you to get the best of native paneling and persistent sessions.

https://www.iterm2.com/documentation-tmux-integration.html


To me, tmux only makes sense for remote servers. Why would I want to use it for local terminal sessions? Why not just have multiple terminal windows open? And multiple desktops instead of "sessions", etc?

I use tmux with iTerm integration when SSH'd into remote machines, so that my tabs/window layout are preserved on the remote server when I reboot/reconnect.

But why would I need that locally? iTerm already saves my windows and tabs/layout/etc... because I don't close them.

Using tmux locally just seems like extra steps... when should I "actually" close a window, and when should I just detach it? Why is the distinction even important? If I don't want to see a window I can just minimize it, and if I want to actually close it, I can just... do that. Maybe because tmux has nice keyboard combos for doing window arrangement? But couldn't I just set up my window manager to do the same?

Remote servers though, totally makes sense. Sometimes you have to disconnect your SSH session, so that you can reboot your local machine while leaving the session open. tmux is a necessary thing in that regard. But on a local machine, rebooting means I'm clearing all my state anyway, so what would it really mean to "resume" a tmux session?

Maybe I just don't get it?


I saw my manager masterfully move his cursor across his terminal, select some text, and copy it, all without using his mouse, inside tmux. I thought it was cool


Isn't a mouse generally better at that?

I mean I generally consider my self pretty good at vim (people who watch me are generally pretty impressed at least), and I get the draw to using the keyboard for things, but the actual act of highlighting arbitrary text, vim is not particularly good at. And I can't imagine how tmux would be either.


> Isn't a mouse generally better at that?

I won’t comment on which is better, but tmux lets you navigate the screen (and history buffer) by searching and vi(1)-like movements which serve me well. To say nothing of being in a situation where there essentially is no mouse...


Tap-tap-tapping your cursor around a row or column at a press is painful. But getting around by searching is often pretty effective - I don't know who wins in a race but it's fast enough not to break my flow.


one of my favorite tmux patterns is "kill it if its running and run it again somewhere else" which uses send keys in a bash script. I'm always knocking up scripts like this

    #!/bin/bash

    TMUX_SESSION=test
    TMUX_WINDOW=QUICK_TEST
    # your custom command you want run
    COMMAND=~/bin/quick_test  
    ARGS=$*

    tmux kill-window -t $TMUX_SESSION:$TMUX_WINDOW
    tmux new-window -t $TMUX_SESSION -n $TMUX_WINDOW
    tmux send-keys -t $TMUX_SESSION:$TMUX_WINDOW"$COMMAND $ARGS" C-m
run the script in the terminal/ide you're working/editing. it blinks away on another screen (or another machine entirely eg. raspberry pi monitor in the kitchen) without disrupting your main task.


Portability I guess? And you can get some pretty nice integration with vim or emacs if you live in the terminal. In fact, it’s probably easier to write a few bash functions to dispatch a command to a new pane than it is to tailor a solution to every OS you might use.

iterm’s Tmux setup is fantastic but if you’re switching between Linux and mac and WSL and want a consistent environment, then you’ve got a good reason to set up Tmux to your liking.


> And multiple desktops instead of "sessions", etc?

I don't like multiple desktops; I like being able to switch panes/windows without losing sight of other applications, like editors and browser windows.


I use tmux locally for multiple sessions. Each session has a different development project. You can achieve the same thing with iterm by having multiple iterm sessions I suppose but I like staying inside one terminal.


Why not have different virtual desktops, each with their own set of iTerm windows?


Personally, I use environment variables inherited by the multiplexer (and then by any shells inside it) to tune my shell to a particular context. There's therefore a useful difference between "give me a new top-level window" in my window manager and "give me a fresh shell in the same context" in my multiplexer.


If you're a Linux user, a logical extension of this idea is to use a tiling window manager, and then you get the paneled window management for everything, not just your terminal.

Being able to detach and re-attach to sessions is still really useful, but I never find myself wanting to use tmux for splitting up a terminal window when I'm already using a tiling window manager.


I never got into those, because I have two modes of working. When I'm writing code, my hands are on the keyboard and I have several splits open and a vim session. When I'm doing anything else, I like to use a mouse because it gives me random access to windows.


"I never find myself wanting to use tmux for splitting up a terminal window when I'm already using a tiling window manager"

I don't want to launch extra terminal instances every time I want to split my terminal window. Also, there's no easy way to detach or reattach to separate terminals as there is to tmux. Nor is there an easy way to programmatically pass information to or from them while they are in the background or off-screen, etc.

That's not to say that separate terminal windows aren't useful. They are, and I sometimes use them myself (particularly for drop-down terminals like guake or terminals in i3's scratchpad).


I've been a long-time user of both i3wm and tmux. If I had to mention a single reason for using tmux, it would be sessions (ie restarting X11 would keep the session alive). There are also some features like searching for text in open windows, that aren't available to a tiling window manager. It's not only about tiling. I also found that restoring tmux sessions (tmux-resurrect+tmux-continuum) was faster than restoring i3 workspaces.


Not for me.

I like my terminals tiled (hence tmux) and everything else free floating.

People say a tiled wm makes you more productive. But most of my time goes to thinking, I don't work in a factory...


I spend most of my day in terminals. If you are mostly just after tiling windows then I prefer, Tilix on Linux or iTerm on Mac OS. The only time I use tmux is if I am worried about losing my ssh connection and don't want my process to die.


Is your connection unstable? Then try Mosh ( https://mosh.org/ )


Usually the title of my terminal window displays some useful informations (e.g. the directory I'm currently in, or if I am installing some packages and their dependencies with "emerge somepackage" then I see what I'm currently emerging, etc...).

Does anybody know how to display the exact same informations in Tmux' bottom green bar? I just want it to display the same stuff that I would otherwise see in the window title of my terminal emulator.

I tried to search for it but I'm probably not using the correct terms so I didn't find anything that is relevant to this.


http://man7.org/linux/man-pages/man1/tmux.1.html#NAMES_AND_T...

    case $TERM in
    xterm*)
        echo -e '\033]0;INSERT TITLE HERE\007';;
    screen*)
        echo -e '\033kINSERT TITLE HERE\033\\';;
    esac
Based on what I do, but not in front of a computer to test exactly what I typed above.


I moved my green bar to the top, but this might do what you need with some minor tweaking.

https://github.com/ohazi/dotfiles/blob/master/tmux.conf#L210...


Can anybody tell me how to scroll up in a tmux session? Whether I use mouse scroll wheel or keyboard, on scrolling up all I get is

^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A


    set -g mouse on
in your ~/.tmux.conf should do the trick.


FYI - after you do this on Mac OS you can't copy to the system clipboard from the buffer using mouse unless you push `fn` before you click on the pane.

I think there are workarounds to get from the tmux copy buffer onto the system clipboard but I usually just `Ctrl-b z` to zoom the pane to full-screen, hold down `fn` button to select text, then `Ctrl-C` like normal.


IIRC, this was fixed in the last few releases- it had to do with OS X's weird user-session/permissions management. At the very least, I was able to comment out the following workaround:

    bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy"
    bind-key -T copy-mode-vi C-j send-keys -X copy-pipe-and-cancel "pbcopy"
    bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
    bind-key -T copy-mode-vi A send-keys -X append-pipe-and-cancel "pbcopy"


I'm using iTerm2 + tmux:

1. If I click my mouse to drag and select what I want to copy, the selection is copied to the clipboard when I release. Selection is highlighted with a yellow background.

2. If I want to double-click to copy, I just hold down the `option` key, then double click and it is copied to the clipboard. Selection is highlighted with a white background.

In both instances, I don't even need to use `ctrl+c`.


Yep, although there are plugins to integrate the tmux clipboard with the system clipboard. I use tmux-yank:

https://github.com/tmux-plugins/tmux-yank


I don't understand why this is not the default behavior.


Different mouse settings send different strings.

You may not way to scroll by accident if your application can use scrolling for changing commands like psql

You may want to do mouse scroll only if you initiated scrolling with say Shift+Page Up

(for me, all the above)


> I don't understand why this is not the default behavior

I would guess it's because a lot of tmux users don't use a mouse on the text console.


See my comments here:

https://github.com/ohazi/dotfiles/blob/master/tmux.conf#L69-...

This is what I mean when I say that tmux config is unintuitive. Ideally there should be one or two directives needed to make this work. It took me weeks to get as far as I did, and I'm still not completely happy with it.


Using the keyboard, I just type my prefix key followed by PageUp.

After that, I can use the PageUp, PageDown, arrow keys, and vi movement keys to move around.

I hit the RETURN or ENTER key to exit.


control-b + pageup control-b + pagedown


I spend about 70+% of my day in tmux. I usually have 15-16 windows (which I work hard to keep pared down), and some key windows with 6 panes (that I have muscle memory regarding what they are precisely doing). I've got a fairly tight 242 line .tmux.conf that I git sync between my various workstations, with affordance for Linux/macOS/WSL to handle things like the clipboard.

In addition to just keeping all my states managed cleanly, a couple of the many key features that I love about tmux:

o No need for a mouse - this has been a life saver in the past when I was working on a customer site, and they had me locked down on a terminal environment where there wasn't any mouse pass-through for things like copy paste.

o tmux restore/resurrect are a godsend. I can do weekly kernel updates on windows-fast ring/lose power, and get all of my sessions and scrollback history

o A side benefit of the restore/resurrect capability, is that I can tar-ball my session state and have all my scroll back and commands on a separate system.

One of nice tweaks that has made a difference for me is creating new-windows and requiring they be named -

   bind-key u command-prompt -p "WinName: " "neww -n %1"
that Ensures all my windows have a name that makes sense.

Love tmux, though, you can go down a rabbit-hole tweaking out your .tmux.conf.


Is there a way to copy the whole tmux window buffer over ssh connection to a Linux or Windows system? So far I only saw iterm2 tmux control mode supporting this on osx. I saw lots of terminals have feature requests open for this functionality but none of them have traction on getting this feature implemented due to the lack of tmux control mode documentation. Terminator has a fork release supporting it but it did work well when I tried it.


Tmux supports your local clients clipboard, so if you are in a tmux-session from your local client, you can copy your scrollback history (or window), into the clipboard, and just paste it locally. I do precisely that dozens of times a day.


One more interest feature which was not clearly described: you can attach two or more ssh connections (belonging to the same system user) to the same tmux session. Each displays the same thing in real time and has full control.

We use this all the time for these two use cases:

1. Semi-permanent connections to the same tmux session on the server from multiple locations e.g. work and home. Come home and find things exactly the way you left them at work, and vice versa.

2. A sort of collaborative environment. We have something like “demo” user running tmux session, and multiple people from different remote locations login as “demo” and attach to the same tmux session. Again, everyone has full control and we can see each other’s actions as we also talk on the voice call in parallel. Usually much better experience vs. some sort of screen+control sharing solution, especially when some participants are on low-quality connections.


Suggestion for your bash_login or equivalent, to automatically get back your session based on the IP you connect from (6to4 safe):

REMOTEIP=`echo $SSH_CONNECTION |sed -e 's/::ffff://g' -e 's/ .*//g'`

if [ -z "$SSH_CONNECTION" ]; then if [ "$TERM" != "tmux" ]; then tmux attach -t $REMOTEIP || tmux new -s $REMOTEIP ; fi ; fi

I have static IPs and I like to come back to a server the way I left it the day before, from home or work.

For pratical reasons (everything in one window), I often have tmux running inside GNU screen, with one GNU screen per remote server.


I don't go too crazy with tmux stuff, I am a very minimal user

This is how I tend to start/restore a session:

    alias foo='tmux a -dt foo || tmux new -s foo'


I wouldn't personally say that tmux is superior to something like iTerm2, but on WSL (Windows Subsystem for Linux) there doesn't seem to be a superior alternative since I haven't found a decent terminal on this OS that supports tiling.


You can also run tmux within Emacs. Start a term via <ESC>x then enter term and press return. You can now run tmux. Use Ctrl-C Ctrl J and Ctrl-C Ctrl K to switch between modes.


I have used tmux non-stop since discovering and love it


Does tmux have anything like screen -R?


Nothing like -R, but attaching tmux lets you swap the client between different sessions with `<your prefix> L` for last, `s` for an interactive list or `(`, `)` for next/previous, and some others I forget.

If you want to list sessions before attaching then there's `tmux ls` :)


tmux attach


tmux new-session -A [-s <session name>]


The list of benefits is missing the main one: you don't have to touch your mouse again.


tmux could really do with a 'vim-sensible' common sensible default configuration.

Mirroring typical linux mouse copy-behaviour is perticularly painful (esp. in a multi-pane setup).




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: