Create a gist now

Instantly share code, notes, and snippets.

Runs the specified command (provided by the first argument) in all tmux panes for every window regardless if applications are running in the terminal or not.
#!/bin/bash
# Runs the specified command (provided by the first argument) in all tmux panes
# for every window regardless if applications are running in the terminal or not.
function execute_in_all_panes {
# Notate which window/pane we were originally at
ORIG_WINDOW_INDEX=`tmux display-message -p '#I'`
ORIG_PANE_INDEX=`tmux display-message -p '#P'`
# Assign the argument to something readable
command=$1
# Count how many windows we have
windows=$((`tmux list-windows | wc -l` - 1))
# Loop through the windows
for (( window=0; window <= $windows; window++ )); do
tmux select-window -t $window #select the window
# Count how many panes there are in the window
panes=$((`tmux list-panes| wc -l` - 1))
# debugging
#echo "window:$window pane:$pane";
#sleep 1
# Loop through the panes that are in the window
for (( pane=0; pane <= $panes; pane++ )); do
# Skip the window that the command was ran in, run it in that window last
# since we don't want to suspend the script that we are currently running
# and also we want to end back where we started..
if [ $ORIG_WINDOW_INDEX -eq $window -a $ORIG_PANE_INDEX -eq $pane ]; then
continue
fi
tmux select-pane -t $pane #select the pane
# Send the escape key, in the 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... also sending a sleep 1 command seems to fuck up the loop.
for i in {1..25}; do tmux send-keys C-[; done
# temp suspend any gui thats running
tmux send-keys C-z
# if no gui was running, remove the escape sequence we just sent ^Z
tmux send-keys C-H
# run the command & switch back to the gui if there was any
tmux send-keys "$command && fg 2>/dev/null" C-m
done
done
tmux select-window -t $ORIG_WINDOW_INDEX #select the original window
tmux select-pane -t $ORIG_PANE_INDEX #select the original pane
# Send the escape key, in the 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... also sending a sleep 1 command seems to fuck up the loop.
for i in {1..25}; do tmux send-keys C-[; done
# temp suspend any gui thats running
# run the command & switch back to the gui if there was any
tmux send-keys C-c "$command && fg 2>/dev/null" C-m
tmux send-keys "clear" C-m
}
execute_in_all_panes "echo OH HAI"
@yubink
yubink commented Sep 3, 2012

Thanks for the script! One suggestion: I would recommend looping over panes and windows using the list-windows/list-panes like such:

  for window in `tmux list-windows -F '#I'`; do 
  for pane in `tmux list-panes -F '#P'`; do

This prevents the script from breaking if the windows were moved to an odd index using move-window. (I commonly move my 0 index window to something else since 0 is far away from my prefix key, backtick (`)).

@ELLIOTTCABLE

@yubink: set-option -g base-index 1

@gryftir
gryftir commented Jan 17, 2014

if the command fails, I think the fg is never called. "$command; fg 2>/dev/null" may be better

@kaushalmodi

I have this binding in my .tmux.conf to run specified command in 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\""

Usage:
E
Enter the command in tmux command prompt: source ~/.alias; clear

@shedd
shedd commented Mar 31, 2014

@kaushalmodi that seems perfect, thanks!!

@Doron-Behar

Thanks @kaushalmodi! You just made my day :)

@Doron-Behar

@kaushalmodi I have managed to run tmux bind <your long command> and it worked great but would it be possible that you could write it in a way that fits ~/.tmux.conf? I recieved an error about this command when I just copied and pasted it in my ~/.tmux.conf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment