我想编写一个 shell 脚本,它将附加到一个名为 tmux 会话,在该会话中选择一个窗口(或窗格),并在选定的窗口(或窗格)中运行一个命令。
我如何通过 Bash 脚本执行此操作?
我知道
tmux new-window -n:mywindow 'exec something'
允许我向新创建的窗口发送命令,但我需要类似
tmux select-window -t:0 'my command'
我想我可以使用send-keys
但似乎应该有一些可以接受命令或运行的命令列表的东西。
答案1
每个tmux窗格是单个 pty(伪 tty)的接口。非分割窗口只有一个窗格;分割窗口有多个窗格。
tmux一旦窗格已使用其初始命令启动,则不提供向其添加额外进程的方法。由初始命令的进程(通常是 shell)为该终端提供作业控制1 。
如果您想要破坏窗格中当前正在运行的任何内容,您可以使用它respawn-pane -k
来终止现有命令并将其替换为新命令(例如respawn-pane -t sessionname:0.4 -k 'some -new command'
)。
但是,如果您想保留窗格中当前正在运行的内容,那么可能没有比简单地使用“键入”更好的选择了send-keys
。
您可以像这样编写脚本(最后附加,否则脚本将等待您分离后再继续):
session=whatever
window=${session}:0
pane=${window}.4
tmux send-keys -t "$pane" C-z 'some -new command' Enter
tmux select-pane -t "$pane"
tmux select-window -t "$window"
tmux attach-session -t "$session"
请注意,在send-keys
命令中,您实际上应该键入字母
E n t e r,以告诉tmux
向窗口发送换行键。(当然,每个命令都以键结尾Enter。)
1作业控制是使用 tty 作为控制终端的单个会话的多个进程组之间的仲裁。即Ctrl+ Zsuspend 键以及jobs
、fg
和bg
shell 命令。
答案2
您可以使用C-m
代替Enter
。 效果是一样的。此外,使用或tmux
可以轻松发送到右/左窗格。如果您想在另一个窗口中寻址窗格,只需在其前面加上窗口编号和句点,例如。-t right
-t left
-t 0.right
现在,您可以编写一个简单的 Bash 函数来获取键序列作为参数并轻松地将其发送到目标窗格。
答案3
将命令添加到简单文本文件队列:
如果您确实想在最后一个命令之后运行该命令而不终止它,这只是最后的手段。
例子
- 编写一个 bash 脚本,将 [cli 命令] 和 [tmux 窗格名称] 作为变量
- 该脚本将命令添加到队列文件中,并将该文件命名为仅适用于该窗格
- 然而队列文件的第一行仅仅是 0 或 1
- 脚本循环尝试将 0 改为 1通过 tmux send-keys 命令发送到相应的 tmux 窗格. (如果窗格中当前正在运行命令,则 send-keys 命令自然不执行任何操作。否则,它将 0 更改为 1。)
- 在同一个循环中,脚本尝试检测队列文件中的 1。
- 当脚本检测到 0 是 1 时,它会运行队列中的下一个命令,并将其从文件中删除。它将 1 改回 0。
要存储命令,你也可以使用“关联数组”
当数组为空时,脚本停止循环。