วิธีการส่งคำสั่งไปยังบานหน้าต่างทั้งหมดใน tmux?


191

ฉันชอบที่จะเรียก:clear-historyบานหน้าต่างที่มีการเลื่อนใหญ่ อย่างไรก็ตามฉันต้องการสคริปต์วิธีส่งคำสั่งนี้ไปยังบานหน้าต่างทั้งหมดในหน้าต่างต่างๆ

ฉันรู้วิธีการส่งคำสั่งไปยังหน้าต่างทั้งหมดได้รับความอนุเคราะห์จากคำถามนี้แต่ฉันจะส่งคำสั่งไปยังบานหน้าต่างทั้งหมดที่หน้าต่างนั้นได้อย่างไร

send-keysและsynchronize-panesจาก manpage tmux มาถึงใจ แต่ฉันไม่แน่ใจว่าจะแต่งงานกันอย่างไร แต่อาจมีวิธีที่ง่ายกว่าในการทำเช่นนี้

ข้อสังเกตพิเศษ:

คิดเกี่ยวกับเรื่องนี้เล็กน้อยtmux list-panes -aดูเหมือนว่าจะแสดงบานหน้าต่างทั้งหมดในเซสชันปัจจุบัน ค่อนข้างมีประโยชน์ในการเริ่มต้นด้วย ฉันจะไปจากที่นี่ที่ไหน


สำหรับผู้ที่มาที่คำถามนี้ด้วยความหวังในการหาวิธีการแก้ปัญหาที่ใช้กับแต่ละบานหน้าต่างในแต่ละหน้าต่างในแต่ละเซสชั่น: scripter.co/command-to-every-pane-window-session-in-tmux
chb

คำตอบ:


355

คุณลองต่อไปนี้ในหน้าต่าง tmux ที่มีหลายบานหน้าต่าง

Ctrl-B :

setw synchronize-panes on

clear history

53
เพียงเพื่อประโยชน์ของความสมบูรณ์เพื่อปิดถ้าคุณต้องการCtrl-b :setw synchronize-panes off
มิทช์

19
และคุณสามารถผูกทางลัดสำหรับสิ่งนี้ได้~/.tmux.confโดยเพิ่ม: bind -n C-x setw synchronize-panes on และ bind -n M-x setw synchronize-panes off
guneysus

4
เป็นไปได้ที่จะตั้ง shorcut แบบเดียวกันสำหรับการสลับ?
Arnold Roa

20
@ArnoldRoa on/offใช่ตัวเลือกที่จะสลับถ้าคุณปล่อยให้ ดังนั้นbind -n C-x setw synchronize-panes
ความรู้สึกที่

1
หากฉันเพิ่มทางbind -n C-x setw synchronize-panesลัดใดฉันควรกดเพื่อเรียกใช้ มันคือคำนำหน้า + C & x ฉันลองตัวเลือกมากมาย
Bill Goldberg

29

บิตปลายไปงานเลี้ยง แต่ฉันไม่ต้องการที่จะล้างชุดและประสานบานหน้าต่างเพียงเพื่อส่งคำสั่งหนึ่งดังนั้นฉันสร้างฟังก์ชั่นห่อหุ้มรอบ tmux send-keys-all-panesและเพิ่มฟังก์ชั่นที่กำหนดเองที่เรียกว่า

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

ฉันยังสร้าง wrapper รอบคำสั่ง tmux เพื่อทำให้การเรียกใช้ฟังก์ชันนี้ง่ายขึ้น (เพื่อความสะดวก) เสื้อคลุมและโค้ดข้างต้นทุกคนที่นี่

สิ่งนี้ทำให้ฉันสามารถเรียกใช้tmux send-keys-all-panes <command>หรือtmux skap <commandส่ง<command>ไปยังบานหน้าต่างทั้งหมด

โปรดทราบว่า tmux เป็นนามแฝงในฟังก์ชั่น wrapper ของฉัน tmux_pp


นี้คือการทุบตี แต่ก็สามารถทำเช่นเดียวกันจากคำสั่ง tmux ผมหมายถึงโดยการทำprefix + :
Rho พี

ฉันไม่รู้ว่าเป็นไปได้หรือไม่ สถานการณ์การใช้งานกรณีที่คุณต้องการส่งคำสั่งผ่าน<prefix>:อะไร
kshenoy

ฉันอยากจะแนะนำการเรียกตัวอย่าง bash ( : run "yourscript.sh yourargs..."); หากคำสั่งของคุณมีเอาต์พุตที่บานหน้าต่างใช้งานหรือที่ระบุจะแสดงผลลัพธ์จนกว่าคุณจะกด q แต่ในกรณีนี้มันไม่ควร แน่นอนคุณสามารถนามแฝง / ผูกนี้เพื่อความชอบของคุณ กระบวนการด้านในอาจตีความการกดแป้นพิมพ์ของคุณหรือเอฟเฟกต์ต่าง ๆ ดังนั้นรายการที่อนุญาตหรือบัญชีดำ#{pane_current_cmd}อาจจำเป็น ฉันมี ctrl + k ถูกผูกไว้เพื่อส่ง ctrl + l และประวัติที่ชัดเจน ใช้งานได้ดีกับกระสุน แต่ปิดบังบัฟเฟอร์ของ Vim ฉันต้องการการปรับแต่งก่อนที่จะออกอากาศ ctrl + k ของฉัน
John P

นี่อาจเป็นปัญหาของ XY มากกว่า พรอมต์คำสั่ง Tmux มีประโยชน์ แต่ดูเหมือนว่าคุณกำลังใช้อยู่เพราะคุณไม่มีพรอมต์คำสั่งอื่นเปิดอยู่ คุณสามารถตั้งค่าการรวมคีย์ - โดยไม่มีคำนำหน้าถ้าคุณต้องการ - เพื่อสลับและโฟกัสบานหน้าต่างพิเศษด้วยเชลล์ที่คุณเลือกแทนที่จะส่ง<prefix>:ก่อนแต่ละคำสั่งสูญเสียเอาต์พุตหลังจากออกคำสั่งและข้อผิดพลาดทั้งหมดที่ มาพร้อมกับการดำเนินการผ่าน Tmux ตัวอย่างเช่น<prefix>:run "man cat"ไม่ส่งผลให้คนปรากฏในpidof manหรือแม้กระทั่งps auxf | grep manและเป็น 'น้อย' เพจเจอร์ปัจจุบันของฉันสำหรับผู้ชาย
John P

ลิงค์นั้นตาย
Mateusz Piotrowski

10

อัปเดตมิถุนายน 2562

ภาพประกอบรวดเร็วในการกำหนดค่าของคุณเองที่มีผลผูกพันสำหรับบานหน้าต่างตรงกัน

เพิ่มต่อไปนี้ลงในของฉันtmux.conf(ความเห็นอย่างแน่นอนนำไปใช้กับการกำหนดค่าโดยรวมของฉัน):

# 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

<C-a><C-y>ตอนนี้ฉันสามารถสลับความสามารถในการประสานคำสั่งผ่านบานหน้าต่างหลายกับ

(ใช่ฉันทำการแมปคีย์การเชื่อมโยงใหม่เป็น Ctrl a)


4

คำตอบข้างต้นไม่เหมาะกับฉัน (tmux v2.3) แต่สิ่งนี้ทำได้จากบรรทัดคำสั่ง bash:

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

สคริปต์ที่ถูกทำให้เป็นมาตรฐานมากขึ้นสำหรับคำสั่ง tmux นอกเหนือจาก 'clear-history' จะแทนที่องค์ประกอบนั้นด้วยพารามิเตอร์เช่น $ 1 ระวังหากคุณต้องการเขียนสคริปต์เพื่อจัดการชุดคำสั่ง tmux เนื่องจาก "-t $ {_ pane}" จะต้องใช้กับแต่ละรายการ

โปรดทราบว่าจำเป็นต้องใช้-aพารามิเตอร์เพื่อtmux list-panesครอบคลุมบานหน้าต่างทั้งหมดในหน้าต่างทั้งหมดในทุกเซสชัน หากไม่มีสิ่งนั้นบานหน้าต่างในหน้าต่าง tmux ปัจจุบันของคุณเท่านั้นที่จะได้รับผลกระทบ หากคุณเปิดเซสชัน tmux มากกว่าหนึ่งเซสชันและต้องการใช้คำสั่งกับบานหน้าต่างภายในเซสชันปัจจุบันเท่านั้นให้แทนที่-aด้วย-s(ทั้งหมดอยู่ในหน้า man ของ tmux)

ฉันไม่ได้ให้คะแนน mod เพื่อแสดงความคิดเห็นโดยตรงกับคำตอบแต่ละข้อข้างต้นดังนั้นนี่คือเหตุผลที่พวกเขาไม่ได้ทำงานให้ฉัน:

ปัญหาที่ฉันมีกับคำตอบของ @ shailesh-garg คือการซิงค์ส่งผลกระทบเฉพาะคำสั่งที่ออกภายในบานหน้าต่างไม่ใช่คำสั่ง tmux ที่ใช้Ctrl-B :ซึ่งอยู่นอกบานหน้าต่าง

ปัญหาสามข้อที่ฉันมีกับคำตอบของ @kshenoy คือ:

  1. มันส่งการกดแป้นไปที่ภายในบานหน้าต่างไม่ใช่ไปยังการดำเนินการ tmux ของบานหน้าต่างนั้นตัวอย่างเช่นหากมีเปลือกทุบตีที่ทำงานในบานหน้าต่างและหนึ่งใช้สคริปต์เพื่อส่ง จะปรากฏในบรรทัดคำสั่ง bash วิธีแก้ไขคือส่ง "tmux clear-history" หรือ pre-pend "tmux" เป็น "$ @" แต่ฉันไม่ได้แก้ไขคำตอบเพราะปัญหาอื่น ๆ ของฉันกับคำตอบ;
  2. ฉันไม่สามารถหาวิธีส่งอักขระขึ้นบรรทัดใหม่ได้โดยไม่ทำลายเส้น
  3. แม้ว่าฉันจะทำอย่างนั้นการส่ง "tmux clear-history" ก็ไม่มีผล

3

รุ่น tmux ของฉันคือ 1.9a และมันใช้งานได้สำหรับฉันปุ่มเดียวก็เพียงพอสำหรับทั้งเปิดและปิด

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  

แทนที่ "session id" และ "command" ตามลำดับ


อยากจะพูดอะไรเกี่ยวกับภาษาต่างประเทศนี้
Muhammad Omer Aslam

อะไร? ภาษาอังกฤษไม่ยาก แต่ถ้าคุณมีสิ่งที่จะพูดแล้วก็พูด
RJ

4
:Dเพื่อนคุณต้องเพิ่มคำอธิบายลงในคำตอบของคุณเนื่องจากมีข้อความน้อยมากและด้วยเหตุนี้ Stackoverflow ตรวจพบว่าเป็นสแปมหรือโพสต์คุณภาพต่ำเพียงเพิ่มรายละเอียดลงไปเพื่อที่จะไม่ปรากฏภายใต้
Muhammad Omer Aslam

6
นั่นเป็นเรื่องตลกคำตอบที่ได้รับการยอมรับนั้นไม่มีคำอธิบายและรหัสเท่านั้น แต่อย่างใด
RJ

0

นี่คือฟังก์ชั่นยูทิลิตี้ของฉันที่จะทำเพียงดำเนินการคำสั่งเมื่อไม่มีอะไรทำงานในบานหน้าต่าง

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

ตัวอย่างการกำหนดเป้าหมายเซสชันที่เรียกว่า dev เปิดใช้งาน python virtualenv ในบานหน้าต่างทั้งหมดที่อยู่ในbashหรือzshหลีกเลี่ยงการดำเนินการคำสั่งในบานหน้าต่างด้วย vim หรือปฏิบัติการอื่น ๆ :

_send_bash_command_to_session dev workon myvirtualenv

หรือจำง่ายกว่า: ทำในเซสชันปัจจุบัน:

tmux_set_venv myvirtualenv

ค้นหาไฟล์กำหนดค่าของฉันด้วยฟังก์ชั่นนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.