50

I launch multipane tmux window to monitor several server parameters. With Ctrl-S I can open a new window with another monitor command.

Now I want to bind Ctrl-Q to open another multipane window with several monitors. How do I bind a key to multiple commands? I tried chaining them with ; and \; - nothing helps. Please, advise what should I use instead of ... below.

Is it possible when I open a new window to suspend the background commands overlapped by it?

    tmux new-session "monitor1" \;\
            split-window -v "monitor2" \;\
            select-pane -U \;\
            split-window -v -h -p 60 "monitor3" \;\
            bind-key -n C-s new-window "monitor4" \;\
            bind-key -n C-q "..."

5 Answers 5

53

Todd Freed is right, the "correct" way to do this is using \;. Sort of. But there's a snag.

You see, you join a sequence of tmux commands together by giving tmux the conjunction ;. Thus, in a file sourced by tmux, you might say

new-session "monitor1" ; split-window -v "monitor2"

if, for some reason, you wanted that all on one line. Now, you can give that one-line compound statement to the tmux command from a shell also but the ; must be escaped so that the shell interprets it as another argument for tmux. Thus the equivalent of the above from the shell is

$ tmux new-session "monitor1" \; split-window -v "monitor2"

Similarly, the tmux bind-key command takes a series of arguments which are the tmux command and arguments to run when the key is pressed. If you wanted to bind C-q to the above sequence from inside a file sourced by tmux, you'd say

bind-key -n C-q new-session "monitor1" \; split-window -v "monitor2"

Here we've escaped the ; from tmux, so that tmux doesn't interpret it as the end of the bind-key command, but as another argument to bind-key telling it to form a compound command as the bound value of the C-q key.

So what happens when we want to make tmux do that from the shell? A whole lot of escaping.

$ tmux bind-key -n C-q new-session "monitor1" \\\; split-window -v "monitor2"

First, we have to escape the \ and the ; each from the shell, causing the shell to pass the two characters \; as an argument to tmux. This then escapes the ; from tmux, causing it to assign the entire compound statement as the binding of C-q.


Now, all that said, if you use a complex tmux setup like this repeatedly, I'd suggest that you create a tmux file to keep it in:

# In split-windows.tmux:
new-session "monitor1"
split-window -v "monitor2"
bind-key -n C-s new-window "monitor4"
# ...etc...

And then:

$ tmux source split-windows.tmux  # (or even make an alias for this)

It'll be a lot easier to maintain that way.

1
  • 4
    To make binding keys to multiple commands from the command line less horrible to look at, you can also string escape the \;: $ tmux bind-key -n C-q new-session "monitor1" '\;' split-window -v "monitor2"
    – Tim Heap
    Commented Sep 5, 2013 at 0:59
20

So the real answer is : you chain commands with a backslash followed by a semicolon.

bind-key C send-keys foo \; send-keys bar

You would put that in your tmux.conf, or run from the tmux ":" prompt

5
  • this was great and worked for using nested tmux session and navigating through the nested tmux windows.
    – Paul
    Commented Dec 16, 2015 at 14:01
  • 1
    This does not work from shell command line. I.e. `tmux bind-key C send-keys foo \; send-keys bar" has the effect of binding "foo" to "C" but prints "bar" immediately.
    – Lqueryvg
    Commented Dec 3, 2016 at 17:00
  • Yes, you would run that from within tmux. Updated to clarify.
    – Todd Freed
    Commented Dec 4, 2016 at 2:37
  • Nice! This totally works... muchas gracias!
    – Brad Parks
    Commented Aug 30, 2018 at 18:30
  • Note: a ; inside single quotes does not need escaping
    – elig
    Commented Aug 3, 2019 at 13:54
2

You are able to do this with a small workaround. Similar to the answer suggesting a script to run (which handles your case well), it can more generally be done by using "run-shell" and calling tmux itself as the shell command.

bind-key z run-shell "tmux send-keys "xyz" ; tmux clear-history; clear" 

which will send 'xyz' keys, tmux 'clear-history' command, and then call the 'clear' shell builtin.

The entire string is just a multiple shell command sequence.

2

Everything shown here will not work, because this

bind q send-keys "command1" \; send-keys "command2"

will execute the command2 immediately and q will be bound only to send-keys "command1"

Here's the solution:

bind R source-file "$HOME/.tmux/reload.tmux"

In the file ~/.tmux/reload.tmux put multiple commands like:

source-file "$HOME/.tmux.conf" 
display-message "Configuration reloaded."
1
  • 1
    Oh wait, use what Peeja said (\\\;) :-)
    – lzap
    Commented Apr 3, 2013 at 11:04
1

You can add something like this to the key bindings to your .tmux.conf file:

bind q send-keys "/home/jackhab/bin/tmux-new-session.sh" \; send-keys "Enter"

And in tmux-new-session.sh you can have:

#! /usr/bin/env bash
tmux new-session "monitor1"
tmux split-window -v "monitor2"
tmux select-pane -U
tmux split-window -v -h -p 60 "monitor3"
...
exit

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .