The central enemy of reliability is complexity.
― Geer et al., 2003
If you are using lots of command line tools (being a cool guy, you should!), you most probably have a need to organize all this stuff. If you are a web developer for example, you want to edit files, have a look on your webserver logs, monitor automated tests, handle your git repo and so on. There is a lot of stuff going on there!
All these tools want to be tamed, to achieve your most productive work flow. Handling lots of separate terminal windows often is not the most efficient thing. That’s where tmux comes into play.
tmux simply stands for “terminal multiplexer” and is an alternative to the well known screen. It’s most obvious use is to manage multiple terminals. This could also be achieved by using a window manager with tiling support like xmonad or KWin. The benefit of tmux here is, that it works within a terminal. Thus it can be used via ssh on a remote server without a GUI.
Here is an example session, used to work on my PhD thesis:
It is built with a client/server architecture. This allows to use it for (remote) pair programming. Furthermore you could put your tmux session on a remote server and have a persistent working environment at hand everywhere.
You can define the layout of your tmux sessions and execute commands when starting it. This way it is easy to kick off your working environment with all the stuff you need to be productive right away. There are even more things you could do with it, but let us rather have a look on how to use it!
In recent Linux distributions you should have a tmux package available. So installation should be as easy as:
$ sudo apt-get install tmux
You would be ready to go for it, by starting a new tmux session via
$ tmux new-session
But I would recommend you also have a look at tmuxinator. This nice ruby gem simplifies the setup of your tmux sessions. For example you would want to create a specific session for a web development project. When starting the session it would automatically change the directory and fire up all your tools like servers and the editor. (If you do not want to use a ruby gem for that, you can achieve the same thing with shell scripts.)
So let’s also install tmuxinator :
$ gem install tmuxinator
tmuxinator wants to start your favorite editor, so make sure you set an environment variable $EDITOR accordingly. Also put this in your ~/.bashrc:
[[ -s $HOME/.tmuxinator/scripts/tmuxinator ]] && source $HOME/.tmuxinator/scripts/tmuxinator
I will show you now, how to get a nice setup for a Ruby on Rails project. Feel free to adapt it to your own needs.
Create a new project with tmuxinator first:
$ tmuxinator new awesome_app
This will create a yaml setup file in ~/.tmuxinator/ and should fire up your editor with that file. If not, just open it by hand.
Within this file, you setup a project name and a directory for that project first. All shell commands you provide will be executed in this directory.
You can also specify a gemset for rvm to use (I prefer to have a .rvmrc file, so I leave it empty) and a command which gets executed prior during startup with pre.
After that you should provide the layout you want to have. Under tabs you put all the windows you want to have: First give it a name and if you want to, also provide a shell command to be run in that window.
For example server: rails s will create a window called ‘server’ and start the rails server in it.
If you want to have multiple panes within a window, you can also provide these in the yaml configuration. Define which tmux layout you want to use with layout:
A basic Ruby on Rails project environment could look like this:
# ~/.tmuxinator/awesome_app.yml # you can make as many tabs as you wish... project_name: awesome_app project_root: ~/git_repos/awesome_app socket_name: foo # Not needed. Remove to use default socket rvm: pre: tabs: - editor: layout: main-vertical panes: - vim - git fetch - console: rails c - capistrano: - server: rails s - logs: tail -f log/development.log
It has 5 windows, the first one called ‘editor’ has two panes. One pane starts up with vim editor, whereas the other pane executes git fetch on startup. Thus we automatically have the latest changes from our remote git repo and vim at hand. The other windows start with the rails console, an empty shell (I am using it for capistrano stuff, thus the name), the rails server and finally a window which holds most recent log output.
To start working with this setup simply type
$ tmuxinator awesome_app
and you are ready to go, having an up-to-date repo, a running server and your editor right in place. mux is an alias for tmuxinator so you could also use mux awesome_app instead.
To get help for tmux commands simply hit Ctrl+B ? to show all the tmux commands. You should easily figure out, how to move around between windows and panes. If you want to exit your tmux session you could either do Ctrl+B :kill-session (kills the session) or Ctrl+B d (detach only, session persists).
You can also configure lots of tmux behavior by editing ~/.tmux.conf. Here is my configuration:
# act like vim setw -g mode-keys vi bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R bind-key -r C-h select-window -t :- bind-key -r C-l select-window -t :+ # act like GNU screen unbind C-b set -g prefix C-a # look good set -g default-terminal "xterm-256color"
Should be self explaining mostly, first block makes tmux keys more vim-like. Also I am changing the tmux prefix binding to Ctrl+A. I had quite some trouble getting colors right within tmux: Using the last setting here and defining the $TERM via a bash alias in ~/.bashrc finally did the trick:
alias tmux='TERM=xterm-256color tmux -2' alias tmuxinator='TERM=xterm-256color tmuxinator' alias mux='TERM=xterm-256color mux'
As I already said in the beginning, there is a lot of other stuff you could do and learn with tmux. But this article should get you going to use it in your daily work, providing easily accessible working environments.