Skip to content

@deshawnbw /execute_in_all_panes.sh
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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

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

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:
<tmux PREFIX> E
Enter the command in tmux command prompt: source ~/.alias; clear

@shedd

@kaushalmodi that seems perfect, thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.