Emacs, scripting and anything text oriented.

Send a command to every pane/window/session in tmux

Kaushal Modi

Faster way to send the same command to each and every pane in your tmux session.

<2018-03-20 Tue>
Optimize the list-panes + send-keys tmux commands, rewrite the post.

Ever wondered how you would send the clear command to each pane, in each window, in each session in tmux, or how you would do source your shell config file in each after each tweak?

Here are few excerpts from my .tmux.conf that allow doing just that.

Send command to all panes in all sessions #

Thanks to the tip in comments from Bob Fleming, I learned that tmux has a -a switch for the list-panes command.

From man tmux,

list-panes [-as] [-F format] [-t target]
              (alias: lsp)
        If -a is given, target is ignored and all panes on the server
        are listed.  If -s is given, target is a session (or the
        current session).  If neither is given, target is a window (or
        the current window).  For the meaning of the -F flag, see the
        FORMATS section.

With that knowledge, the older version of the E binding now reduces to,

# Send the same command to all panes/windows/sessions
bind E command-prompt -p "Command:" \
       "run \"tmux list-panes -a -F '##{session_name}:##{window_index}.##{pane_index}' \
              | xargs -I PANE tmux send-keys -t PANE '%1' Enter\""

Usage #

  • Type the following binding in any tmux pane: C-z E1
  • Enter a command that you would want to send to all the panes, like source ~/.alias; clear (this is entered in the tmux command prompt).
  • That will source the ~/.alias in all panes, and then clear the terminals as well.

About the ## #

The # character needs to be escaped by another # and typed as ##, only when used inside the run-shell command.

.. because otherwise, tmux run-shell command will replace the unescaped #{session_name}, #{window_index} and #{pane_index} with their current values before executing the command.

With the hashes escaped, those variables will be evaluated at run time.

But if you were to type the above command directly in the terminal, without the run-shell command wrapper, you would use only single #:

tmux list-panes -s -F "#{session_name}:#{window_index}.#{pane_index}"

Send command to all panes in current session #

The list-panes command has another useful switch: -s, which takes an optional argument, a session name. If that argument is not supplied, it takes the current session name by default.

Below C-e binding is used to send a command to all panes, in all windows, but only in the current session.

bind C-e command-prompt -p "Command:" \
         "run \"tmux list-panes -s -F '##{session_name}:##{window_index}.##{pane_index}' \
                | xargs -I PANE tmux send-keys -t PANE '%1' Enter\""

Older version (circa 2014) #

# Send the same command to all panes/windows/sessions
bind E command-prompt -p "Command:" \
       "run \"tmux list-sessions                                           -F '##{session_name}' \
              | xargs -I SESS          tmux list-windows  -t SESS          -F 'SESS:##{window_index}' \
              | xargs -I SESS_WIN      tmux list-panes    -t SESS_WIN      -F 'SESS_WIN.##{pane_index}' \
              | xargs -I SESS_WIN_PANE tmux send-keys     -t SESS_WIN_PANE '%1' Enter\""

  1. I have set my tmux prefix to C-z. [return]

Versions used: tmux 2.6+

If you have written a response to this, enter your response post's URL below.

Or, you can send a "comment" webmention (it's OK if you don't know what that means). When asked about your website on an IndieAuth login screen, simply type https://commentpara.de.

Markdown Support**bold**, _italics_, ~~strikethrough~~, [descr](link), `monospace`, ```LANG\nline1\nline2\n``` (Yep, multi-line code blocks too, with syntax highlighting!), auto-hyperlinking.

Webmentions #

Comment by bob fleming on Tue Mar 20, 2018 05:47 EDT

awesome job. made my head hurt a bit though so i created this alternative:

bind E command-prompt -p "Command:" \
"run \"tmux list-panes -a -F '##{session_name}:##{window_index}.##{pane_index}' | xargs -I PANE tmux send-keys -t PANE '%1' Enter\""

Comment by Kaushal Modi on Tue Mar 20, 2018 08:15 EDT
Replying to comment by bob fleming: "awesome job. made my head hurt a …"

If I understand correctly, that's not an exact alternative.. you are sending the commands to all panes, but only in the current window in the current session. If that's all you need, you can make it simpler by just using the pane synchronization feature.

Comment by bob fleming on Tue Mar 20, 2018 11:04 EDT
Replying to comment by Kaushal Modi: "If I understand correctly, that's …"

actually that's not correct, at least in tmux 2.6. list-panes is very configurable, but the call above list all panes in all windows and sessions.

Comment by Kaushal Modi on Tue Mar 20, 2018 11:44 EDT
Replying to comment by bob fleming: "actually that's not correct, at …"

Ah, OK! I got it now.. I missed the "-a" option.. that option
probably wasn't there when I wrote this post 4 years back :). From the manuals: "If -a is given, target is ignored and all panes on the server are listed.". So time to update this post.. thanks! :D

Comment by Kaushal Modi on Tue Mar 20, 2018 16:50 EDT
Replying to comment by bob fleming: "actually that's not correct, at …"

I've updated the post with your info, thanks.