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

Liv*_*vid 5 tmux shell-script

我最近花了很多时间摆弄 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
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

Kam*_*ski 4

\n

看来我的要求被忽略了

\n
\n\n

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

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

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

\n
\n\n

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

\n\n

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

\n\n

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

\n\n
+---------------------+\n|       1             |\n|22222221             |\n|   3   1             |\n|   3   1#############|\n|   3   1             |\n|22222221             |\n|       1             |\n+---------------------+\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n
\n\n

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

\n\n
+---------------------+\n|       #             |\n|       #             |\n|       ##############|\n|       |       |     |\n|       |       |     |\n|---------------|     |\n|               |     |\n+---------------------+\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
\n\n

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

\n\n
#!/bin/sh\n\nsession="$USER"\nwindow="$session:1"\n\nlines="$(tput lines)"\ncolumns="$(tput cols)"\n\ntmux -2 new-session -d -x "$columns" -y "$lines" -s "$session" \'echo "step -1"; bash\'\ntmux new-window -t "$window" -n \'Logs\' \'echo "step 0"; bash\' || exit\n\ntmux split-window -t "$window"             -h -p 67    -d \'echo "step 1";  bash\'\ntmux split-window -t "$window"             -v -p 10 -b -d \'echo "step 2a"; bash\'\ntmux split-window -t "$window"             -v -p 22    -d \'echo "step 2b"; bash\'\ntmux split-window -t "$window"             -h -p 50       \'echo "step 3";  bash\'\ntmux split-window -t "$window.{top-right}" -v -p 55    -d\ntmux split-window -t "$window.{top-right}" -v -p 64\ntmux select-pane  -t "$window.{bottom-right}"\ntmux split-window -t "$window"             -v -p 67\ntmux split-window -t "$window"             -v -p 50\n\ntmux select-window -t "$window"\n\n# Attach to session\ntmux -2 attach-session -t "$session"\n
Run Code Online (Sandbox Code Playgroud)\n\n

笔记:

\n\n
    \n
  • 舍邦是/bin/sh,这里不需要 Bash。
  • \n
  • 习惯双引号变量。不管你是否需要,习惯性地引用它,比在真正产生影响时忘记引用要好得多。
  • \n
  • 对变量使用小写名称
  • \n
  • 我用来tput确定当前终端的大小。然后new-session -d -x \xe2\x80\xa6 -y \xe2\x80\xa6使用适当的值。但是:\n\n
      \n
    • 在我最初的测试中,这似乎是不必要的,所有这些都可以在没有-x-y\xe2\x80\xa6 的情况下工作
    • \n
    • \xe2\x80\xa6 尽管根据我的本地手册,这应该是必要的。
    • \n
    • 无论如何,如果会话已经存在,则其大小已确定并且new-session -d -x \xe2\x80\xa6 -y \xe2\x80\xa6不会产生任何影响。附加并调整窗格大小后,您可能会遇到布局比例扭曲的情况。有一些 tmux 命令和选项可能会有所帮助(resize-windowwindow-sizedefault-size),尽管在我的老式 tmux 中没有,所以我不会详细说明。
    • \n
    • tput操作数lines,并且cols不是 POSIX 所必需的。请参阅此答案以获取替代方案。
    • \n
  • \n
  • 如果无法创建窗口,则脚本退出。
  • \n
  • 每个split-window目标都针对右侧窗口。如果会话存在或有人同时连接并更改了窗口,则当前窗口将不是您所假设的窗口。为了更加强大,每个都split-window应该明确地针对各自的窗格。请注意,select-panebefore split-window(或resize-pane脚本中的 before)在许多客户端可以与同一 tmux 服务器交互的常规设置中并不是真正强大:其他一些客户端(用户或脚本)可以在这两个命令之间选择另一个窗格。
  • \n
  • 我不调整窗格大小。我首先以适当的百分比创建它们。我使用的选项-p适用于我的老式 tmux。文档告诉我新的语法就像split-window -l 20%并且resize-pane也可以使用百分比。不知道最新的tmux能不能理解split-window -p。文档不再提及此选项,它可能已被弃用且不受支持,或者可能为了兼容性而保留;我无法对此进行测试(欢迎反馈或编辑)。
  • \n
  • split-window取指可用空间的百分比,即即将缩小以为新窗格腾出空间的窗格的旧大小(至少这是它在我的老式 tmux 中的工作方式-p)。这就是为什么22出现类似数字 ( 20/(20+70) \xe2\x89\x88 22 )。根据文档resize-pane使用窗口大小的百分比。
  • \n
  • 我使用或不使用-d保留在当前窗格中或将新窗格设置为当前窗格,具体取决于我需要将下一个窗格作为目标窗格split-window.
  • \n
  • 当我需要指定/选择适合令牌的窗格时,例如{top-right},我使用令牌。
  • \n
  • 我不用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
  • \n
\n\n
\n\n

附加说明:

\n\n
    \n
  • cat /proc/cpuinfo | grep "MHz" | \xe2\x80\xa6是无用的使用cat。更好的方法:

    \n\n
    </proc/cpuinfo grep "MHz" | \xe2\x80\xa6\ngrep "MHz" /proc/cpuinfo  | \xe2\x80\xa6\n
    Run Code Online (Sandbox Code Playgroud)
  • \n
\n