Bagaimana cara mengirim perintah ke semua panel di tmux?

192

Saya suka memanggil :clear-historypanel dengan scrollback besar. Namun, saya ingin menulis cara untuk mengirim perintah ini ke semua panel di berbagai jendela.

Saya tahu cara mengirim perintah ke semua jendela, berkat pertanyaan ini , tetapi bagaimana cara mengirim perintah ke semua panel di jendela mana juga?

send-keys dan synchronize-panes dari manual tmux muncul di pikiran, tapi aku tidak yakin bagaimana menikahi mereka bersama. Tapi mungkin ada cara sederhana untuk melakukan ini.

Pengamatan Ekstra:

Memikirkan hal ini sedikit, tmux list-panes -asepertinya mencantumkan semua panel di sesi saat ini. Cukup berguna untuk memulai. Kemana saya harus pergi dari sini?

Ehtesh Choudhury
sumber
Bagi mereka yang datang ke pertanyaan ini dengan harapan menemukan solusi yang berlaku untuk setiap panel, di setiap jendela, di setiap sesi: scripter.co/command-to-every-pane-window-session-in-tmux
chb

Jawaban:

356

Sudahkah Anda mencoba mengikuti di jendela tmux dengan banyak panel

Ctrl-B :

setw synchronize-panes on

clear history
shailesh garg
sumber
53
Demi kelengkapan, untuk mematikan jika Anda mau lakukanCtrl-b :setw synchronize-panes off
Mitch
19
dan Anda dapat mengikat pintasan untuk ini ~/.tmux.confdengan menambahkan: bind -n C-x setw synchronize-panes on dan bind -n M-x setw synchronize-panes off
guneysus
4
mungkin untuk mengatur shorcut yang sama untuk toggling?
Arnold Roa
20
@ArnoldRoa ya, opsi akan beralih jika Anda pergi on/off. Jadibind -n C-x setw synchronize-panes
sensasi
1
Jika saya menambahkan bind -n C-x setw synchronize-panesjalan pintas apa yang harus saya tekan untuk memohon? Apakah ini awalan + C & x. Saya mencoba banyak opsi
Bill Goldberg
29

Agak terlambat ke pesta tetapi saya tidak ingin mengatur dan menghapus set-sinkronisasi hanya untuk mengirim satu perintah jadi saya membuat fungsi pembungkus di sekitar tmux dan menambahkan fungsi kustom yang disebut send-keys-all-panes.

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

Saya juga membuat wrapper di sekitar perintah tmux untuk mempermudah memanggil fungsi ini (untuk kenyamanan). Wrapper dan kode di atas semuanya ada di sini .

Ini memungkinkan saya untuk menjalankan tmux send-keys-all-panes <command>atau tmux skap <commandmengirim <command>ke semua panel.

Perhatikan bahwa tmux alias fungsi pembungkus saya tmux_pp.

kshenoy
sumber
ini adalah bash, tetapi dapatkah seseorang melakukan hal yang sama dari command prompt tmux, maksud saya dengan melakukanprefix + :
Rho Phi
Saya tidak tahu bagaimana atau apakah itu mungkin. Apa skenario use-case Anda yang harus Anda kirimi perintah <prefix>:?
kshenoy
Saya akan merekomendasikan memanggil bash snippet ( : run "yourscript.sh yourargs..."); jika perintah Anda menghasilkan panel Anda yang aktif atau yang ditentukan akan menampilkan hasilnya sampai Anda menekan q, tetapi dalam kasus ini seharusnya tidak. Tentu saja Anda dapat alias / mengikat ini sesuai dengan keinginan Anda. Selain itu, proses internal dapat menginterpretasikan penekanan tombol atau efeknya secara berbeda, sehingga daftar putih atau daftar hitam #{pane_current_cmd}mungkin diperlukan. Saya memiliki ctrl + k terikat untuk mengirim ctrl + l dan menghapus riwayat; ini berfungsi dengan baik untuk kerang, tetapi penyangga climbers Vim. Saya perlu perbaikan sebelum saya bisa menyiarkan ctrl + k saya.
John P
Ini mungkin lebih merupakan masalah XY; command prompt Tmux berguna, tetapi sepertinya Anda menggunakannya karena Anda tidak memiliki command prompt terbuka. Anda dapat mengatur ikatan kunci - tanpa awalan, jika Anda suka - untuk beralih dan memfokuskan panel tambahan dengan shell pilihan Anda, alih-alih mengirim <prefix>:sebelum setiap perintah, kehilangan output setelah meninggalkan perintah, dan semua jebakan yang datang dengan mengeksekusi melalui Tmux. Sebagai contoh, <prefix>:run "man cat"tidak menghasilkan pria muncul pidof manatau bahkan ps auxf | grep man, atau 'kurang', pager saya saat ini untuk pria.
John P
Tautannya sudah mati
Mateusz Piotrowski
10

Perbarui Juni 2019

Ilustrasi cepat tentang cara mengonfigurasi ikatan Anda sendiri untuk panel sinkronisasi .

Menambahkan yang berikut ke dalam saya tmux.conf(komentar tentu berlaku untuk konfigurasi saya secara keseluruhan):

# 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

Sekarang, saya dapat mengaktifkan kemampuan untuk menyinkronkan perintah di beberapa panel dengan <C-a><C-y>.

(Ya, saya memetakan kembali kunci ikat ke Ctrl a).

arcseldon
sumber
4

Tidak ada jawaban di atas yang berfungsi untuk saya (tmux v2.3), tetapi ini berhasil, dari baris perintah bash:

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

Skrip yang lebih umum, untuk perintah tmux selain dari 'clear-history' hanya akan mengganti elemen itu dengan parameter, misalnya. $ 1. Berhati-hatilah jika Anda bermaksud menulis skrip untuk menangani serangkaian perintah tmux, karena "-t $ {_ pane}" perlu diterapkan untuk masing-masingnya.

Perhatikan bahwa -aparameter untuk tmux list-panesdiperlukan untuk mencakup semua panel di semua jendela di semua sesi. Tanpa itu, hanya panel di jendela tmux Anda saat ini yang akan terpengaruh. Jika Anda memiliki lebih dari satu sesi tmux terbuka dan hanya ingin menerapkan perintah ke panel dalam sesi saat ini, ganti -adengan -s(Semuanya ada di halaman manual tmux).

Saya tidak memiliki mod poin untuk mengomentari langsung setiap jawaban di atas, jadi inilah mengapa mereka tidak bekerja untuk saya:

Masalah yang saya miliki dengan jawaban @ shailesh-garg adalah bahwa sinkronisasi hanya mempengaruhi perintah yang dikeluarkan dalam panel, bukan perintah tmux yang dikeluarkan menggunakan Ctrl-B :yang berada di luar panel.

Tiga masalah yang saya miliki dengan jawaban @kshenoy adalah:

  1. ia mengirim penekanan tombol ke dalam panel, bukan ke operasi tmux panel itu, jadi misalnya, jika seseorang memiliki bash shell yang berjalan di panel dan satu menggunakan skrip untuk mengirim "clear-history", itu akan menjadi penekanan tombol yang akan muncul di baris perintah bash. Solusi untuk mengirim "tmux clear-history" atau ke pre-pend "tmux" ke "$ @", tetapi saya belum mengedit jawaban karena masalah saya yang lain dengan jawaban;
  2. Saya tidak tahu bagaimana cara mengirim karakter baris baru tanpa benar-benar melanggar garis;
  3. Bahkan ketika saya melakukan itu, mengirim "tmux clear-history" tidak berpengaruh.
pengguna1404316
sumber
3

versi tmux saya adalah 1.9a, dan ini berfungsi untuk saya, satu kunci sudah cukup baik untuk hidup dan mati

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

Ganti "id sesi" dan "perintah" sesuai.

RJ
sumber
ingin mengatakan sesuatu tentang bahasa asing ini
Muhammad Omer Aslam
Apa? Bahasa Inggris tidak sulit. Tetapi jika Anda memiliki sesuatu untuk dikatakan, katakan saja.
RJ
4
:DBung Anda perlu menambahkan beberapa deskripsi untuk jawaban Anda karena memiliki teks yang sangat minim dan untuk alasan itu Stackoverflow mendeteksinya sebagai spam atau posting berkualitas rendah hanya menambahkan beberapa detail untuk itu sehingga tidak muncul di bawahnya.
Muhammad Omer Aslam
6
Itu lucu, jawaban yang diterima juga tidak memiliki deskripsi dan hanya kode, tetapi apa pun.
RJ
0

Ini adalah fungsi utilitas saya untuk melakukannya, hanya menjalankan perintah ketika tidak ada yang berjalan di 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
}

Contoh menargetkan sesi yang disebut dev, mengaktifkan python virtualenv di semua panel yang ada di bashatauzsh , menghindari mengeksekusi perintah di panel dengan vim atau yang dapat dieksekusi lainnya:

_send_bash_command_to_session dev workon myvirtualenv

atau lebih mudah diingat: untuk melakukannya di sesi saat ini:

tmux_set_venv myvirtualenv

Temukan file konfigurasi saya dengan fungsi ini.

phcerdan
sumber