If you use tmux in your terminal you probably have a default set-up you use. For example, I always have the same windows open with the same names split up in the same way at work, so I decided I might as well make a script to avoid all that manual work each time.
The easiest way to do this is with a bash script. The basic trick is to start a tmux session detached and then send it signals. Here’s a very basic script to start a tmux session named vim
with vim running in it and then attach:
The first line of this script (after the shebang bash line) says to make a new tmux session named vim
but don’t attach to it. The second line sends the text vim
to the target session vim
then hits enter (represented by C-m
). That will cause vim to start in the opened tmux session. Finally, we attach to the session vim
. Simple, right?
Let’s see an example with more windows and splits:
This script is a little more complicated. First we start a new session called work
and remain detached. Then we rename the window to vim
. Then we start vim in that window. Next, we open a new window, rename it server
and send the command ./bin/rails s
to it (this generally starts the web server in a rails project). Next, we split the window and send ./bin/sidekiq
to that split. Finally, we select window number 1 (I have my tmux windows start numbering at 1, but your might start at 0) and attach to the tmux session.
Some things to know that might help you:
- When you open a new window to split, your cursor is assumed to be in that pane for when you use
send-keys
. You generally want to send the keys to your current pane before splitting or opening a new window. - If you don’t like to have your windows split into even-size panes there are ways to specify the size, but I find they can have wildly different effects if you use the same script on computers with different size monitors. As a result, I don’t worry about resizing panes in the script.
- You can put the name of your session in a variable (i.e.
SESSION=work; tmux new -s $SESSION -d
) so you can easily rename it in the future.
I think you can see how these scripts are starting to get useful. I had a problem, though. At my job we run a lot of our development stuff in a vagrant vm. So I wanted to start vagrant, and then run several commands that depend on vagrant having successfully started. Vagrant takes a while to start, however, so I needed to find a way to wait for a single command to complete before proceeding. Luckily, tmux can help us here.
The second line of this script does exactly what we need. The way it works is this: tmux send-keys
sends a command to tmux and doesn’t care what happens as a result. After the send-keys
command, though, we say wait-for vagrant-up
, which means the script will wait until a wait-for
command with the arbitrary name vagrant-up
is sent from the tmux session. The way you send this command is tmux wait-for -S vagrant up
, so our tmux session is actually sending that back to us after the vagrant up
command has completed. Since the wait-for
command has been sent, the script can continue with other commands that can assume vagrant is running.
I hope you have fun writing your own tmux scripts!