Come inviare un comando a tutti i riquadri in tmux?


192

Mi piace chiamare i :clear-historyriquadri con un enorme scrollback. Tuttavia, voglio scrivere un modo per inviare questo comando a tutti i riquadri nelle varie finestre.

So come inviare un comando a tutte le finestre, grazie a questa domanda , ma come posso inviare un comando a tutti i riquadri di quella finestra?

send-keyse synchronize-panesdalla tmux manpage mi viene in mente, ma non sono sicuro di come sposarli insieme. Ma forse c'è un modo più semplice per farlo.

Osservazioni extra:

Pensandoci un po ', tmux list-panes -asembra elencare tutti i riquadri della sessione corrente. Abbastanza utile per iniziare. Dove vado da qui?


Per coloro che arrivano a questa domanda nella speranza di trovare una soluzione che si applichi a ciascun riquadro, in ciascuna finestra, in ogni sessione: scripter.co/command-to-every-pane-window-session-in-tmux
chb

Risposte:


356

Hai provato a seguire in tmux window con più riquadri

Ctrl-B :

setw synchronize-panes on

clear history

53
Solo per ragioni di completezza, di trasformare se fuori si farebbeCtrl-b :setw synchronize-panes off
Mitch

19
e puoi legare le scorciatoie per questo ~/.tmux.confaggiungendo: bind -n C-x setw synchronize-panes on e bind -n M-x setw synchronize-panes off
guneysus

4
è possibile impostare lo stesso shorcut per alternare?
Arnold Roa,

20
@ArnoldRoa sì, l'opzione si disattiva se si esce on/off. Quindibind -n C-x setw synchronize-panes
sensazione

1
Se aggiungo bind -n C-x setw synchronize-panesquale scorciatoia devo premere per invocare? È prefisso + C & x. Ho provato molte opzioni
Bill Goldberg il

29

Un po 'in ritardo alla festa, ma non volevo impostare e annullare la sincronizzazione dei pannelli solo per inviare un comando, quindi ho creato una funzione wrapper attorno a tmux e ho aggiunto una funzione personalizzata chiamata send-keys-all-panes.

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

Creo anche un wrapper attorno al comando tmux per semplificare la chiamata a questa funzione (per comodità). Il wrapper e il codice sopra sono tutti qui .

Questo mi permette di eseguire tmux send-keys-all-panes <command>o tmux skap <commandinviare<command> a tutti i riquadri.

Nota che tmux è aliasato per la mia funzione wrapper tmux_pp.


questo è bash, ma si può fare lo stesso dal prompt dei comandi di tmux, intendo facendoprefix + :
Rho Phi

Non so come o se sia possibile. Qual è lo scenario del tuo caso d'uso per cui devi inviare un comando <prefix>:?
kshenoy

Consiglierei di chiamare lo snippet bash ( : run "yourscript.sh yourargs..."); se il comando ha emesso il riquadro attivo o specificato verranno visualizzati i risultati fino a quando non si preme q, ma in questo caso non dovrebbe. Naturalmente puoi alias / associarlo a tuo piacimento. A parte questo, i processi interni possono interpretare i tasti premuti oi loro effetti in modo diverso, quindi #{pane_current_cmd}potrebbe essere necessaria una lista bianca o una lista nera . Ho ctrl + k per inviare ctrl + le clear-history; questo funziona bene con le conchiglie, ma blocca il buffer di Vim. Avrei bisogno di un perfezionamento prima di poter trasmettere il mio ctrl + k.
John P

Questo potrebbe essere più di un problema XY; il prompt dei comandi di Tmux è utile, ma sembra che tu lo stia utilizzando perché non hai un altro prompt dei comandi aperto. È possibile impostare un'associazione di tasti - senza il prefisso, se lo si desidera - per attivare e mettere a fuoco un riquadro aggiuntivo con la shell di scelta, invece di inviare <prefix>:prima di ogni comando, perdere l'output dopo aver lasciato il comando e tutte le insidie ​​che vieni con l'esecuzione attraverso Tmux. Ad esempio, <prefix>:run "man cat"non risulta che l'uomo appaia pidof mano addirittura ps auxf | grep man, né come "meno", il mio cercapersone attuale per l'uomo.
John P

Il link è morto
Mateusz Piotrowski il

10

Aggiornamento giugno 2019

Illustrazione rapida su come configurare il proprio binding per sincronizzare i riquadri .

Aggiunto quanto segue nel mio tmux.conf(i commenti si applicano sicuramente alla mia configurazione generale):

# 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

Ora, posso attivare la possibilità di sincronizzare i comandi su più riquadri con <C-a><C-y> .

(Sì, ho rimappato il tasto di associazione a Ctrl a).


4

Nessuna delle risposte di cui sopra ha funzionato per me (tmux v2.3), ma ha funzionato, dalla riga di comando bash:

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

Uno script più generalizzato, per comandi tmux diversi da "clear-history" sostituirà semplicemente quell'elemento con un parametro, ad es. 1 $. Fai attenzione se intendi scrivere uno script per gestire una serie di comandi tmux, poiché "-t $ {_ pane}" dovrà essere applicato a ciascuno.

Si noti che il -aparametro to tmux list-panesè necessario per coprire tutti i riquadri in tutte le finestre in tutte le sessioni. Senza di ciò, saranno interessati solo i riquadri nella finestra corrente di tmux. Se hai più di una sessione di tmux aperta e desideri applicare il comando solo ai riquadri della sessione corrente, sostituisci -acon-s (È tutto nella pagina man di tmux).

Non ho i punti mod per commentare direttamente ciascuna delle risposte sopra, quindi ecco perché non stavano lavorando per me:

Il problema che ho avuto con la risposta di @ shailesh-garg era che la sincronizzazione riguardava solo i comandi emessi all'interno dei riquadri, non i comandi tmux emessi usando Ctrl-B : che sono al di fuori dei riquadri.

I tre problemi che ho avuto con la risposta di @kshenoy sono stati:

  1. invia sequenze di tasti all'interno di un riquadro, non all'operazione tmux di quel riquadro, quindi per esempio, se uno avesse una shell bash in esecuzione nel riquadro e uno usasse lo script per inviare "clear-history", quelli sarebbero i tasti che apparirebbe nella riga di comando bash. Una soluzione alternativa sarebbe inviare "tmux clear-history" o pre-pend "tmux" a "$ @", ma non ho modificato la risposta a causa dei miei altri problemi con la risposta;
  2. Non riuscivo a capire come inviare un personaggio di nuova linea senza letteralmente spezzare la linea;
  3. Anche quando l'ho fatto, l'invio di "tmux clear-history" non ha avuto alcun effetto.

3

la mia versione di tmux è 1.9a, e questo funziona per me, una chiave è sufficiente per accendere e spegnere

bind-key X set-window-option synchronize-panes\; display-message "synchronize-panes is now #{?pane_synchronized,on,off}"

2
tmux send-keys -t <session id> <command> C-m  

Sostituire "ID sessione" e "comando" di conseguenza.


vorrei dire qualcosa su questa lingua aliena
Muhammad Omer Aslam,

Che cosa? L'inglese non è difficile. Ma se hai qualcosa da dire, allora dillo.
RJ

4
:Damico devi aggiungere una descrizione alla tua risposta in quanto ha un testo molto minimo e per questo motivo Stackoverflow lo rileva come uno spam o un post di bassa qualità semplicemente aggiungendo alcuni dettagli in modo che non appaia sotto di esso.
Muhammad Omer Aslam,

6
È divertente, anche la risposta accettata non ha una descrizione e solo il codice, ma comunque.
RJ

0

Questa è la mia funzione di utility per farlo, eseguendo il comando solo quando non c'è nulla in esecuzione nel riquadro.

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

Esempio indirizzato a una sessione chiamata dev, abilitando un virtualenv python in tutti i riquadri in basho zsh, evitando di eseguire il comando in riquadri con vim o qualsiasi altro eseguibile:

_send_bash_command_to_session dev workon myvirtualenv

o più facile da ricordare: per farlo nella sessione corrente:

tmux_set_venv myvirtualenv

Trova il mio file di configurazione con questa funzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.