在正在运行的 tmux 会话中运行或向 tmux 窗格发送命令

在正在运行的 tmux 会话中运行或向 tmux 窗格发送命令

我想编写一个 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 键以及jobsfgbgshell 命令。

答案2

您可以使用C-m代替Enter。 效果是一样的。此外,使用或tmux可以轻松发送到右/左窗格。如果您想在另一个窗口中寻址窗格,只需在其前面加上窗口编号和句点,例如。-t right-t left-t 0.right

现在,您可以编写一个简单的 Bash 函数来获取键序列作为参数并轻松地将其发送到目标窗格。

答案3

将命令添加到简单文本文件队列:

如果您确实想在最后一个命令之后运行该命令而不终止它,这只是最后的手段。

例子

  1. 编写一个 bash 脚本,将 [cli 命令] 和 [tmux 窗格名称] 作为变量
  2. 该脚本将命令添加到队列文件中,并将该文件命名为仅适用于该窗格
  3. 然而队列文件的第一行仅仅是 0 或 1
  4. 脚本循环尝试将 0 改为 1通过 tmux send-keys 命令发送到相应的 tmux 窗格. (如果窗格中当前正在运行命令,则 send-keys 命令自然不执行任何操作。否则,它将 0 更改为 1。)
  5. 在同一个循环中,脚本尝试检测队列文件中的 1。
  6. 当脚本检测到 0 是 1 时,它会运行队列中的下一个命令,并将其从文件中删除。它将 1 改回 0。

要存储命令,你也可以使用“关联数组”

当数组为空时,脚本停止循环。

相关内容