如何以编程方式在 tmux 中获取此布局?

如何以编程方式在 tmux 中获取此布局?

我最近花了很多时间摆弄 tmux,但无法弄清楚我做错了什么。在我看来,有些布局根本就是不允许的。没有抛出任何错误或警告,但似乎我的请求被简单地忽略了。这是我的目标:

在此输入图像描述

这是我已经能够实现的目标:

在此输入图像描述

这是我正在运行的 shell 脚本:

#!/bin/bash
SESSION=$USER

tmux -2 new-session -d -s $SESSION


tmux new-window -t $SESSION:1 -n 'Logs'
tmux split-window -h
tmux split-window -h
tmux split-window -v
tmux split-window -v


tmux select-pane -t 0
tmux resize-pane -L 100
tmux send-keys 'watch -n1 "cat /proc/cpuinfo | grep "MHz" | sort -r | head -32"' C-m

tmux select-pane -t 1
tmux resize-pane -L 100
tmux send-keys 'watch -n1 "cat /proc/cpuinfo | grep "MHz" | sort -r | tail -32"' C-m


tmux send-keys 'watch -n1 inxi -s' C-m


tmux select-pane -t 2
tmux resize-pane -U 50
tmux send-keys 'watch -n1 ${HOME}/bin/clean_sensors.sh' C-m


tmux select-pane -t 3
tmux send-keys 'watch -n1 rocm-smi' C-m

tmux select-pane -t 4
tmux resize-pane -U 7
tmux send-keys 'watch -n1 ${HOME}/bin/gpu_sensors.sh' C-m


# # Set default window
tmux select-window -t $SESSION:1

# Attach to session
tmux -2 attach-session -t $SESSION

编辑: 以下是我对 @KamilMaciorowski 的解决方案的结果:

在此输入图像描述

您可以看到窗口数量是正确的,但相对大小仍然不正确。

答案1

看来我的要求被忽略了

目前尚不清楚哪些请求被忽略。你的脚本对我来说有点用,如果我在没有运行 tmux 服务器的情况下重新运行它,似乎没有什么会被忽略。 tmux 服务器已经运行时存在问题:

  • 该会话可能已经存在并且有人可能正在(主动)使用它,
  • 该窗口可能已经存在,
  • 您的split-window命令可能针对某些其他(预先存在的)窗口。

在我看来,有些布局根本就是不允许的。

如果您的目标是使用已有的布局并通过执行更多操作来获得所需的布局,那么就会很困难,因为你无法轻松获得所需的右上角或右下角窗格整个左侧的“33%”列被分成两个“50%”窗格。您需要以不同的顺序进行拆分。

了解顺序的一种方法是在一张纸上画出布局,然后用剪刀将其剪下直的削减通过,因此每次切割都会将当前块分成两个较小的块。或者想象一下打破一块巧克力。

您想要的布局的可能方案如下:

+---------------------+
|       1             |
|22222221             |
|   3   1             |
|   3   1#############|
|   3   1             |
|22222221             |
|       1             |
+---------------------+

这些数字表示您需要按照什么顺序进行切割。标记为 的剪切#表示右列中的多次剪切,您可以在1、 之前或之后2或后以任何顺序进行剪切3。这些#削减对于这个问题来说并不重要。重要的是你需要在和之后进行两次2切割(以任何顺序)1 3。您的脚本3无需制作即可执行剪辑2,然后就没有直接的方法来获得您想要的内容。

split-window -f,它创建一个跨越整个窗口高度或整个窗口宽度的新窗格,而不是分割单个窗格。虽然它带来了一定的灵活性并允许以不同的顺序创建窗格,但它不会帮助您从已实现的布局中获得所需的布局;它也不会使更多的布局成为可能。


相比之下,我认为这确实是一个不可能的布局:

+---------------------+
|       #             |
|       #             |
|       ##############|
|       |       |     |
|       |       |     |
|---------------|     |
|               |     |
+---------------------+

实际上,你可以用剪刀剪它,但不能用 tmux,因为至少用剪刀剪的第一遍需要弯曲以创建两张单独的纸。第一剪的例子是用#人物画的。你可以将其解释为两个不“通过”的剪切,因此对于 tmux 这种解释没有任何改变,它仍然是不可能的。


这是一个在 tmux 2.3 中适用的示例脚本。备注和改进在代码下方以注释形式列出;请在运行脚本之前阅读它们。

#!/bin/sh

session="$USER"
window="$session:1"

lines="$(tput lines)"
columns="$(tput cols)"

tmux -2 new-session -d -x "$columns" -y "$lines" -s "$session" 'echo "step -1"; bash'
tmux new-window -t "$window" -n 'Logs' 'echo "step 0"; bash' || exit

tmux split-window -t "$window"             -h -p 67    -d 'echo "step 1";  bash'
tmux split-window -t "$window"             -v -p 10 -b -d 'echo "step 2a"; bash'
tmux split-window -t "$window"             -v -p 22    -d 'echo "step 2b"; bash'
tmux split-window -t "$window"             -h -p 50       'echo "step 3";  bash'
tmux split-window -t "$window.{top-right}" -v -p 55    -d
tmux split-window -t "$window.{top-right}" -v -p 64
tmux select-pane  -t "$window.{bottom-right}"
tmux split-window -t "$window"             -v -p 67
tmux split-window -t "$window"             -v -p 50

tmux select-window -t "$window"

# Attach to session
tmux -2 attach-session -t "$session"

笔记:

  • 最重要的是/bin/sh,这里不需要 Bash。
  • 习惯于双引号变量。不管你是否需要,习惯性地引用它,比在真正产生影响时忘记引用要好得多。
  • 我用了变量名称小写
  • 我用来tput确定当前终端的大小。然后new-session -d -x … -y …使用适当的值。但:
    • 在我最初的测试中,这似乎是不必要的,所有这些都可以在没有-x-y……的情况下工作。
    • …尽管根据我当地的手册,这应该是必要的。
    • 无论如何,如果会话已经存在,则其大小已确定并且new-session -d -x … -y …不会产生任何影响。附加并调整窗格大小后,您可能会遇到布局比例扭曲的情况。有一些 tmux 命令和选项可能会有所帮助(resize-windowwindow-sizedefault-size),尽管在我的老式 tmux 中没有,所以我不会详细说明。
    • tput操作数lines,并且cols不是 POSIX 所必需的。看这个答案的替代品。
  • 如果无法创建窗口,则脚本退出。
  • 每个split-window目标都针对右侧窗口。如果会话存在或有人同时连接并更改了窗口,则当前窗口将不是您所假设的窗口。为了更加强大,每个都split-window应该明确地针对各自的窗格。请注意,select-panebefore split-window(或resize-pane脚本中的 before)在许多客户端可以与同一 tmux 服务器交互的常规设置中并不是真正强大:其他一些客户端(用户或脚本)可以在这两个命令之间选择另一个窗格。
  • 我不调整窗格大小。我首先以适当的百分比创建它们。我使用的选项-p适用于我的老式 tmux。文档告诉我新的语法就像split-window -l 20%并且resize-pane也可以使用百分比。不知道最新的tmux能不能看懂split-window -p。文档不再提及此选项,它可能已被弃用且不受支持,或者可能为了兼容性而保留;我无法对此进行测试(欢迎反馈或编辑)。
  • split-window取指可用空间的百分比,即即将缩小以为新窗格腾出空间的窗格的旧大小(至少这是它在我的老式 tmux 中的工作方式-p)。这就是为什么22会出现这样的数字 ( 20/(20+70) ≈ 22 )。根据文档resize-pane使用窗口大小的百分比。
  • 我使用或不使用-d来留在当前窗格中或使新窗格成为当前窗格,具体取决于我需要将下一个split-window.
  • 当我需要指定/选择适合令牌(如 )的窗格时{top-right},我使用令牌。
  • 我不用send-keys来运行命令。一般来说不要用于send-keys运行命令。任何在 tmux 内创建新 shell 的(?) tmux 命令都可以运行 shell 命令。示例脚本中echo "step 0"; bash就是这样的shell命令。它包含bash在末尾,因此当实际命令 ( echo) 完成时,窗格不会退出。另一种选择是remain-on-exit选择。你的 shell 命令 ( watch) 可以无限期地工作,所以你可能不需要这样的技巧。send-keys如果命令影响它运行的 shell,并且您的目标是在以这种方式准备的 shell 中交互工作,则像在脚本中那样运行 shell 命令是有意义的。例如,该命令可以设置变量或获取脚本;或者您希望能够中断watch并将其保存在 shell 历史记录中。在任何其他情况下,“正确”的方法是使用 或一些类似的 tmux 命令传递split-window命令respawn-pane

附加说明:

  • cat /proc/cpuinfo | grep "MHz" | …是无用的使用cat。更好的方法:

    </proc/cpuinfo grep "MHz" | …
    grep "MHz" /proc/cpuinfo  | …
    

答案2

我会先制作左侧,然后制作右侧,每次都按您想要的窗格的比例进行分割:

tmux new -d
tmux splitw -dh
tmux splitw -p90
tmux splitw -dp22 # 20/90
tmux splitw -h
tmux selectp -t'{right}'
tmux splitw -p80
tmux splitw -p56 # (15+15+15)/80
tmux splitw -p50
tmux selectp -t'{top-left}'
tmux a

我只是一次添加一个拆分窗口,然后查看结果以了解当前窗格是哪个窗格以及下一步需要如何拆分。

相关内容