web-dev-qa-db-fra.com

Comment envoyer une commande à tous les volets dans tmux?

J'aime appeler :clear-history sur les volets avec un défilement énorme. Cependant, je souhaite créer un script pour envoyer cette commande à tous les volets des différentes fenêtres.

Je sais comment envoyer une commande à toutes les fenêtres, grâce à cette question , mais comment puis-je envoyer une commande à tous les volets de chaque fenêtre?

send-keys et synchronize-panes de la page de manuel tmux me viennent à l’esprit, mais je ne suis pas sûr de savoir comment les marier ensemble. Mais peut-être existe-t-il un moyen plus simple de procéder.

Observations supplémentaires:

En pensant un peu à cela, tmux list-panes -a semble lister tous les volets de la session en cours. Assez utile pour commencer. Où vais-je d'ici?

137

Avez-vous essayé de suivre dans la fenêtre tmux avec plusieurs volets

Ctrl-B :

setw synchronize-panes on

clear history
257
shailesh garg

Un peu tard pour la soirée mais je ne voulais pas définir et désélectionner synchronize-panes juste pour envoyer une commande, j'ai donc créé une fonction d'encapsulation autour de tmux et ajouté une fonction personnalisée appelée send-keys-all-panes.

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

Je crée également un wrapper autour de la commande tmux pour simplifier l'appel de cette fonction (pour plus de commodité). Le wrapper et le code ci-dessus sont tous ici .

Cela me permet d'exécuter tmux send-keys-all-panes <command> ou tmux skap <command pour envoyer <command> à tous les volets.

Notez que tmux est associé à ma fonction wrapper tmux_pp.

23
kshenoy

Aucune des réponses ci-dessus n'a fonctionné pour moi (tmux v2.3), mais cela a fonctionné à partir de la ligne de commande bash:

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

Un script plus généralisé, pour des commandes tmux autres que 'clear-history', remplacerait simplement cet élément par un paramètre, par exemple. 1 $. Faites attention si vous avez l'intention d'écrire un script pour gérer une série de commandes tmux, car "-t $ {_ pane}" devra être appliqué à chacune d'elles.

Notez que le paramètre -a à tmux list-panes est requis pour couvrir tous les volets de toutes les fenêtres de toutes les sessions. Sans cela, seuls les volets de votre fenêtre tmux actuelle seront affectés. Si vous avez plusieurs sessions tmux ouvertes et souhaitez uniquement appliquer la commande aux volets de la session en cours, remplacez -a par -s (tout se trouve dans la page de manuel tmux).

Je n'ai pas les points de mod à commenter directement sur chacune des réponses ci-dessus, alors voici pourquoi ils ne travaillaient pas pour moi:

Le problème que j'avais avec la réponse de @ shailesh-garg était que la synchronisation affectait uniquement les commandes émises dans les volets, pas les commandes tmux émises à l'aide de Ctrl-B : qui se trouvaient hors des volets.

La réponse de @kshenoy à mes problèmes était la suivante: 

  1. il envoie des frappes dans un volet, et non à l'opération tmux de ce volet, ainsi par exemple, si un shell bash s'exécute. le volet et l'autre à l'aide du script pour envoyer "l'historique clair", ces seraient les frappes au clavier qui apparaîtront dans la ligne de commande bash . Un contournement consisterait à envoyer "tmux clear-history" ou à précéder "tmux" à "$ @ ", mais je n’ai pas modifié la réponse à cause de mon autre problème avec la réponse; 
  2. Je ne savais pas comment envoyer un caractère de nouvelle ligne .__ sans rompre littéralement la ligne; 
  3. Même quand j'ai fait cela, envoyer "tmux clear-history" n'a eu aucun effet.
4
user1404316
tmux send-keys -t <session id> <command> C-m  

Remplacez "l'identifiant de session" et "commande" en conséquence.

2
R J

Mise à jour juin 2019

Illustration rapide sur la façon de configurer votre propre liaison pour synchroniser les volets .

Ajoutez ce qui suit dans mon tmux.conf (les commentaires s'appliquent certainement à ma configuration globale):

# 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

Maintenant, je peux basculer la possibilité de synchroniser des commandes sur plusieurs volets avec <C-a><C-y>.

(Oui, j'ai remappé la clé de liaison en Ctrl a).

1
arcseldon

C’est la fonction que j’ai utilisée pour le faire, n’exécutant la commande que lorsque rien ne s’exécute dans le volet.

#!/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
}

Exemple ciblant une session appelée dev, activant un virtualenv python dans tous les volets de bash ou zsh, évitant d'exécuter la commande dans les volets avec vim ou tout autre exécutable:

_send_bash_command_to_session dev workon myvirtualenv

ou plus facile à retenir: pour le faire dans la session en cours:

tmux_set_venv myvirtualenv

Trouver mon fichier de configuration avec cette fonction. 

0
phcerdan