41

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 "..."
40

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.

| improve this answer | |
  • 3
    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 Sep 5 '13 at 0:59
14

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

| improve this answer | |
  • this was great and worked for using nested tmux session and navigating through the nested tmux windows. – Paul Dec 16 '15 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 Dec 3 '16 at 17:00
  • Yes, you would run that from within tmux. Updated to clarify. – Todd Freed Dec 4 '16 at 2:37
  • Nice! This totally works... muchas gracias! – Brad Parks Aug 30 '18 at 18:30
  • Note: a ; inside single quotes does not need escaping – elig Aug 3 '19 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.

| improve this answer | |
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
| improve this answer | |
1

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."
| improve this answer | |
  • 1
    Oh wait, use what Peeja said (\\\;) :-) – lzap Apr 3 '13 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.