¿Cómo enviar un comando a todos los paneles en tmux?

192

Me gusta recurrir :clear-historya paneles con un enorme desplazamiento hacia atrás. Sin embargo, quiero escribir una forma de enviar este comando a todos los paneles en las distintas ventanas.

Sé cómo enviar un comando a todas las ventanas, cortesía de esta pregunta , pero ¿cómo envío un comando a todos los paneles de qué ventana también?

send-keysy synchronize-panesde la página de manual de tmux me viene a la mente, pero no estoy seguro de cómo casarlos. Pero tal vez hay una manera más simple de hacer esto.

Observaciones extra:

Pensando en esto un poco, tmux list-panes -aparece enumerar todos los paneles en la sesión actual. Bastante útil para comenzar. ¿A donde voy desde aqui?

Ehtesh Choudhury
fuente
Para los que vienen a esta pregunta con la esperanza de encontrar una solución que se aplica a cada panel, en cada ventana, en cada sesión: scripter.co/command-to-every-pane-window-session-in-tmux
CHB

Respuestas:

356

¿Has intentado seguir en tmux window con múltiples paneles?

Ctrl-B :

setw synchronize-panes on

clear history
shailesh garg
fuente
53
Solo por el bien de la integridad, desactivar si lo haríaCtrl-b :setw synchronize-panes off
Mitch
19
y puede enlazar atajos para esto ~/.tmux.confagregando: bind -n C-x setw synchronize-panes on y bind -n M-x setw synchronize-panes off
guneysus
44
¿Es posible establecer el mismo shorcut para alternar?
Arnold Roa
20
@ArnoldRoa sí, la opción cambiará si te vas on/off. Entoncesbind -n C-x setw synchronize-panes
sensación
1
Si agrego bind -n C-x setw synchronize-panes¿qué atajo debo presionar para invocar? ¿Es el prefijo + C y x? Probé muchas opciones
Bill Goldberg,
29

Llegué un poco tarde a la fiesta, pero no quería configurar y desarmar los paneles de sincronización solo para enviar un comando, así que creé una función envolvente alrededor de tmux y agregué una función personalizada llamada send-keys-all-panes.

_tmux_send_keys_all_panes_ () {
  for _pane in $(tmux list-panes -F '#P'); do
    tmux send-keys -t ${_pane} "$@"
  done
}

También creo un contenedor alrededor del comando tmux para simplificar la llamada a esta función (por conveniencia). El contenedor y el código anterior están todos aquí .

Esto me permite ejecutar tmux send-keys-all-panes <command>o tmux skap <commandenviar <command>a todos los paneles.

Tenga en cuenta que tmux tiene un alias para mi función de contenedor tmux_pp.

kshenoy
fuente
esto es bash, pero ¿se puede hacer lo mismo desde el símbolo del sistema tmux, quiero decir al hacerprefix + :
Rho Phi
No sé cómo o si eso es posible. ¿Cuál es su escenario de caso de uso al que necesita enviar un comando <prefix>:?
kshenoy
Recomendaría llamar al fragmento de bash ( : run "yourscript.sh yourargs..."); si su comando ha dado salida, su panel activo o especificado mostrará los resultados hasta que presione q, pero en este caso no debería. Por supuesto, puede alias / vincular esto a su gusto. Además, los procesos internos pueden interpretar sus pulsaciones de teclas o sus efectos de manera diferente, por lo que #{pane_current_cmd}puede ser necesaria una lista blanca o negra . Tengo ctrl + k obligado a enviar ctrl + ly clear-history; Esto funciona bien para las conchas, pero golpea el búfer de Vim. Necesitaría refinamiento antes de poder transmitir mi ctrl + k.
John P
Esto puede ser más un problema XY; el símbolo del sistema de Tmux es útil, pero parece que lo está utilizando porque no tiene otro símbolo del sistema abierto. Puede configurar un enlace de teclas, sin el prefijo, si lo desea, para alternar y enfocar un panel adicional con su caparazón de elección, en lugar de enviar <prefix>:antes de cada comando, perder la salida después de abandonar el comando y todas las trampas que ven con ejecutar a través de Tmux. Por ejemplo, <prefix>:run "man cat"no da como resultado que el hombre aparezca pidof mano ni siquiera ps auxf | grep man, ni como 'menos', mi localizador actual para hombre.
John P
El enlace está muerto
Mateusz Piotrowski
10

Actualización de junio de 2019

Ilustración rápida sobre cómo configurar su propio enlace para sincronizar paneles .

Agregué lo siguiente en mi tmux.conf(los comentarios ciertamente se aplican a mi configuración general):

# synchronize all panes in a window
# don't use control S, too easily confused
# with navigation key sequences in tmux (show sessions)
unbind C-S
bind C-Y set-window-option synchronize-panes

Ahora, puedo alternar la capacidad de sincronizar comandos en múltiples paneles con <C-a><C-y>.

(Sí, reasigné la tecla de enlace a Ctrl a).

arcseldon
fuente
4

Ninguna de las respuestas anteriores funcionó para mí (tmux v2.3), pero esto lo hizo, desde la línea de comando bash:

for _pane in $(tmux list-panes -a -F '#{pane_id}'); do \
  tmux clear-history -t ${_pane}  ; done

Un script más generalizado, para comandos tmux que no sean 'clear-history' simplemente reemplazaría ese elemento con un parámetro, por ejemplo. $ 1. Tenga cuidado si tiene la intención de escribir un script para manejar una serie de comandos tmux, ya que "-t $ {_ pane}" deberá aplicarse a cada uno.

Tenga en cuenta que el -aparámetro to tmux list-paneses necesario para cubrir todos los paneles en todas las ventanas en todas las sesiones. Sin eso, solo los paneles en su ventana tmux actual se verán afectados. Si tiene más de una sesión de tmux abierta y solo desea aplicar el comando a los paneles dentro de la sesión actual, reemplácela -acon -s(Todo está en la página de manual de tmux).

No tengo los puntos de mod para comentar directamente sobre cada una de las respuestas anteriores, así que he aquí por qué no funcionaban para mí:

El problema que tuve con la respuesta de @ shailesh-garg fue que la sincronización afectaba solo a los comandos emitidos dentro de los paneles, no a los comandos tmux emitidos usando los Ctrl-B :que están fuera de los paneles.

Los tres problemas que tuve con la respuesta de @kshenoy fueron:

  1. envía pulsaciones de teclas dentro de un panel, no a la operación tmux de ese panel, por ejemplo, si uno tuviera un shell bash ejecutándose en el panel y utilizara el script para enviar "historial claro", esas serían las pulsaciones de teclas que aparecería en la línea de comando bash. Una solución alternativa sería enviar "tmux clear-history" o pre-pend "tmux" a "$ @", pero no he editado la respuesta debido a mis otros problemas con la respuesta;
  2. No podía entender cómo enviar un personaje de nueva línea sin literalmente romper la línea;
  3. Incluso cuando hice eso, enviar "tmux clear-history" no tuvo ningún efecto.
usuario1404316
fuente
3

mi versión de tmux es 1.9a, y esto funciona para mí, una tecla es suficiente para encender y apagar

bind-key X set-window-option synchronize-panes\; display-message "synchronize-panes is now #{?pane_synchronized,on,off}"
Liu Yue
fuente
2
tmux send-keys -t <session id> <command> C-m  

Reemplace el "id de sesión" y el "comando" en consecuencia.

RJ
fuente
quisiera decir algo sobre este idioma alienígena
Muhammad Omer Aslam
¿Qué? El inglés no es difícil. Pero si tienes algo que decir, dilo.
RJ
44
:Damigo, debe agregar alguna descripción a su respuesta, ya que tiene un texto muy mínimo y, por esa razón, Stackoverflow lo detecta como una publicación de spam o de baja calidad, solo agregue algunos detalles para que no aparezca debajo.
Muhammad Omer Aslam
66
Eso es divertido, la respuesta aceptada tampoco tiene descripción y solo el código, pero lo que sea.
RJ
0

Esta es mi función de utilidad para hacerlo, solo ejecutando el comando cuando no hay nada ejecutándose en el panel.

#!/bin/bash

_send_bash_command_to_session() {
    if [[ $# -eq 0 || "$1" = "--help" ]] ; then
        echo 'Usage: _send_bash_command_to_session $session_name what ever command you want: '
        return
    fi
    input_session="$1"
    input_command="${@:2}"
    for _pane in $(tmux list-panes -s -t ${input_session} -F '#{window_index}.#{pane_index}'); do
        # only apply the command in bash or zsh panes.
        _current_command=$(tmux display-message -p -t ${input_session}:${_pane} '#{pane_current_command}')
        if [ ${_current_command} = zsh ] || [ ${_current_command} = bash ] ; then
            tmux send-keys -t ${_pane} "${input_command}" Enter
        fi
    done
}

tmux_set_venv() {
    _current_session=$(tmux display-message -p '#{session_name}')
    _send_bash_command_to_session ${_current_session} workon $1
}

Ejemplo dirigido a una sesión llamada dev, habilitando un python virtualenv en todos los paneles que están en basho zsh, evitando ejecutar el comando en paneles con vim o cualquier otro ejecutable:

_send_bash_command_to_session dev workon myvirtualenv

o más fácil de recordar: para hacerlo en la sesión actual:

tmux_set_venv myvirtualenv

Encuentra mi archivo de configuración con esta función.

Phcerdan
fuente