Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
tmux: run a command in all panes
#!/bin/bash
# Runs the specified command (provided by the first argument) in all tmux panes
# in every window. If an application is currently running in a given pane
# (e.g., vim), it is suspended and then resumed so the command can be run.
all-panes()
{
all-panes-bg_ "$1" &
}
# The actual implementation of `all-panes` that runs in a background process.
# This prevents the function from being suspended when we press ^z in each pane.
all-panes-bg_()
{
# Assign the argument to something readable
local COMMAND=$1
# Remember which window/pane we were originally at
local ORIG_WINDOW_INDEX=`tmux display-message -p '#I'`
local ORIG_PANE_INDEX=`tmux display-message -p '#P'`
# Loop through the windows
for WINDOW in `tmux list-windows -F '#I'`; do
# Select the window
tmux select-window -t $WINDOW
# Remember the window's current pane sync setting
local ORIG_PANE_SYNC=`tmux show-window-options | grep '^synchronize-panes' | awk '{ print $2 }'`
# Send keystrokes to all panes within the current window simultaneously
tmux set-window-option synchronize-panes on
# Send the escape key in case we are in a vim-like program. This is
# repeated because the send-key command is not waiting for vim to complete
# its action... And sending a `sleep 1` command seems to screw up the loop.
for i in {1..25}; do tmux send-keys 'C-['; done
# Temporarily suspend any GUI that's running
tmux send-keys C-z
# If no GUI was running, kill any input the user may have typed on the
# command line to avoid A) concatenating our command with theirs, and
# B) accidentally running a command the user didn't want to run
# (e.g., rm -rf ~).
tmux send-keys C-c
# Run the command and switch back to the GUI if there was any
tmux send-keys "$COMMAND; fg 2>/dev/null; echo -n" C-m
# Restore the window's original pane sync setting
if [[ -n "$ORIG_PANE_SYNC" ]]; then
tmux set-window-option synchronize-panes "$ORIG_PANE_SYNC"
else
tmux set-window-option -u synchronize-panes
fi
done
# Select the original window and pane
tmux select-window -t $ORIG_WINDOW_INDEX
tmux select-pane -t $ORIG_PANE_INDEX
}
@nathanielks

This comment has been minimized.

Copy link

nathanielks commented Mar 12, 2016

This is awesome, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.