Tmux 的窗格标题

在我的本地机器上,我有3个 node.js 实例同时运行。在名为“服务器”的 tmux 窗口中,每个窗口都有自己的窗格。问题是,要找出哪个节点在哪个窗格中运行并不容易,因为它们的日志相似。

我需要的是每个窗格的标题。正如我得到的,tmux 本身没有这个特性: 它只有窗口的标题,而没有窗格的标题。在每个面板中为每个 node.js 实例启动一个单独的 tmux 会话看起来有点过了。

So is there some small program that launches a command, wrapping its output with a specified status bar?

先谢谢你

87748 次浏览

是的,有这样一个命令: tmux。给你的会话一个名字,它会显示在一个内部状态栏:

TMUX=0 tmux new-session -s my-new-session

Tmux 确实支持每个窗格标题,但是它不提供显示这些标题的每个窗格位置。

您可以使用转义序列 ESC ]2;... ESC \设置窗格的标题(例如,请参阅 TMux手册中名为 Names and Titles的部分)。你可以像这样从外壳开始:

printf '\033]2;%s\033\\' 'title goes here'

每个窗格的标题默认为系统的主机名。默认情况下,活动窗格的标题显示在 TMux状态行的右侧(会话变量 status-right的默认全局值是 "#22T" %H:%M %d-%b-%y,它显示窗格标题、时间和日期的22个字符)。

因此,只要您对能够看到活动窗格的标题感到满意(即愿意切换窗格以看到非活动窗格的标题) ,就可以使用默认功能。在启动每个窗格的主命令之前,只需发送适当的标题设置转义序列。


如果您绝对需要一个专用行来显示一些每个窗格的信息,那么嵌套的 TMux会话可能不会像您最初想象的那样“过度”(不必要)。

在一般情况下,为了在某个给定的终端上提供一条不可侵犯的状态线,您将需要一个位于原始终端和新终端之间的完整终端(re)仿真器(一个只有一条线的终端)。这样的(重新)仿真需要翻译控制序列发送到内部终端和翻译他们为原始终端。例如,要维护外部终端底部的状态行,命令

移到最后一行。

发送到内部终端必须成为

移到最后一行的下一行。

同样地,发送到内部终端的 LF 必须变成

如果光标位于最后一行的下一行,那么将该行及其上面的所有行向上滚动一行,以提供一个清晰的倒数第二行(保护最后一行的状态行)。 否则,发送一个 LF。

在外部终端。

TMuxscreen这样的程序就是这样的终端重仿真器。当然,这个虚拟终端还包含很多其他功能,但是你需要大量的终端模拟代码来提供一个 可靠状态行。


There is, however, a light-weight solution as long as

  1. 您的程序(Node.js实例)与正在运行的窗格的终端交互有限(即没有光标定位) ,以及
  2. 在程序运行时不调整窗格的大小。

像许多终端模拟器一样,TMux在其窗格中支持“设置滚动区域”终端控制命令。您可以使用此命令将滚动区域限制为终端的顶部(或底部) N-1行,并将某种实例标识文本写入非滚动行。

The restrictions (no cursor movement commands allowed, no resizing) are required because the program that is generating the output (e.g. a Node.js instance) has no idea that scrolling has been limited to a particular region. If the output-generating program happened to move the cursor outside of the scrolling region, then the output might become garbled. Likewise, the terminal emulator probably automatically resets the scrolling region when the terminal is resized (so the “non-scrolling line” will probably end up scrolling away).

我写了一个脚本,使用 tput生成适当的控制序列,写入非滚动行,并运行一个程序后移动光标到滚动区域:

#!/bin/sh


# usage: no_scroll_line top|bottom 'non-scrolling line content' command to run with args
#
#     Set up a non-scrolling line at the top (or the bottom) of the
#     terminal, write the given text into it, then (in the scrolling
#     region) run the given command with its arguments. When the
#     command has finished, pause with a prompt and reset the
#     scrolling region.


get_size() {
set -- $(stty size)
LINES=$1
COLUMNS=$2
}
set_nonscrolling_line() {
get_size
case "$1" in
t|to|top)
non_scroll_line=0
first_scrolling_line=1
scroll_region="1 $(($LINES - 1))"
;;
b|bo|bot|bott|botto|bottom)
first_scrolling_line=0
scroll_region="0 $(($LINES - 2))"
non_scroll_line="$(($LINES - 1))"
;;
*)
echo 'error: first argument must be "top" or "bottom"'
exit 1
;;
esac
clear
tput csr $scroll_region
tput cup "$non_scroll_line" 0
printf %s "$2"
tput cup "$first_scrolling_line" 0
}
reset_scrolling() {
get_size
clear
tput csr 0 $(($LINES - 1))
}


# Set up the scrolling region and write into the non-scrolling line
set_nonscrolling_line "$1" "$2"
shift 2


# Run something that writes into the scolling region
"$@"
ec=$?


# Reset the scrolling region
printf %s 'Press ENTER to reset scrolling (will clear screen)'
read a_line
reset_scrolling


exit "$ec"

你可以这样使用它:

tmux split-window '/path/to/no_scroll_line bottom "Node instance foo" node foo.js'
tmux split-window '/path/to/no_scroll_line bottom "Node instance bar" node bar.js'
tmux split-window '/path/to/no_scroll_line bottom "Node instance quux" node quux.js'

只要终端支持并发布其 csrcup终端功能,该脚本也应该在 tmux之外工作。

这在短期内是没有帮助的,但是在 tmux 中有对每个窗格标题的特性请求: http://sourceforge.net/tracker/?func=detail&aid=3495916&group_id=200378&atid=973265#

与此同时,正如其他人提到的,嵌套 tmux 工作得很好。

I'm working on the pane status bar for tmux - ticket. My development branch can be found here on github: Https://github.com/jonathanslenders/tmux

现在,它已经添加了一个工作 “ title”命令。仍然存在一些 bug,API 将得到改进。其思想是在每个窗格中创建一个状态栏,这个状态栏可以有一些格式,比如会话状态栏。与 tmux 的其他部分一样,所有内容都应该是可编写脚本和可定制的。当完成和稳定,它可能会包括在官方的混音。

这个功能已经在 这个承诺中添加到 tmux 中。它不在2.2版本中,但看起来它将在2.3版本中。

启动它:

tmux set -g pane-border-status top

或者你更喜欢:

tmux set -g pane-border-status bottom

要将自定义文本设置为窗格边框状态行,可以使用 pane-border-format,例如:

tmux set -g pane-border-format "#{pane_index} #{pane_current_command}"

我使用的是 tmux 版本2.3,我认为边框样式在以前的版本中是不支持的。 这对我很有效:

为每个窗格设置标题:

printf '\033]2;My Pane Title\033\\'

然后:

tmux set -g pane-border-format "#{pane_index} #T"

一个动图胜过千言万语

Tmux-xpanes 是一个基于 tmux 的终端分割器,它支持 通过新添加的 -t选项显示每个窗格的标题。

由于 tmux 2.6你可以做:

$ tmux select-pane -t {pane} -T {title}


# Examples:
$ tmux select-pane -T title1          # Change title of current pane
$ tmux select-pane -t 1 -T title2     # Change title of pane 1 in current window
$ tmux select-pane -t 2.1 -T title3   # Change title of pane 1 in window 2

您可以在状态栏中看到每个窗格的标题,具有:

$ tmux set pane-border-status bottom      # For current window
$ tmux set -g pane-border-status bottom   # For all windows

使用以下命令禁用状态栏:

$ tmux set pane-border-status off       # For current window
$ tmux set -g pane-border-status off    # For all windows

DR

将以下配置附加到您的 tmux 配置文件(在我的示例中是 ~/.tmux.conf.local)

# dispaly pane_current_path as the pane title
set -g pane-border-status top
set -g pane-border-format "#{pane_index} #{pane_current_path}"

然后跑:

tmux source-file ~/.tmux.con

好好享受吧

Thanks to https://stackoverflow.com/a/37602055/5121972

所有现有的答案都没有提到如何实际更改默认标题,但是解决方案隐藏在 https://unix.stackexchange.com/a/564690/28354中,例如,在 Android Termux tmux 上,你可以将默认标题“ localhost”更改为模型名,就像这样,从 zsh shell 中:

tmux set-hook -g after-split-window "select-pane -T \"$(getprop ro.product.model)\""
tmux set-hook -g after-new-window "select-pane -T \"$(getprop ro.product.model)\""
tmux set-hook -g after-new-session "select-pane -T \"$(getprop ro.product.model)\""

This will change the "localhost" from bottom-right status bar next to the clock, because pane_title is what's used, which, in turn, defaults to the hostname:

% tmux show-options -g status-right
status-right "#{?window_bigger,[#{window_offset_x}#,#{window_offset_y}] ,}\"#{=21:pane_title}\" %H:%M %d-%b-%y"
[0] 0:zsh  1:zsh  2:zsh- 3:zsh*                         "Pixel 2 XL" 22:55 26-Sep-21

此外,它也可以显示在每个窗格的顶部:

tmux set -g pane-border-status top

格式由 pane-border-format控制,默认值如下:

% tmux show-options -g pane-border-format
pane-border-format "#{?pane_active,#[reverse],}#{pane_index}#[default] \"#{pane_title}\""

.tmux.conf中添加这三行可以工作,而且不会干扰 tmux 管理的 pane_title变量

set -g pane-border-status top
set -g pane-border-format "#[fg=black, bg=green] #{pane_index} #{@custom_pane_title}"
bind < command-prompt -p "New Title: " -I "#{@custom_pane_title}" "set-option -p @custom_pane_title '%%'"

添加这些代码行之后,为 .tmux.conf提供源代码以反映更改

tmux source-file ~/.tmux.conf

在 tmux 窗格中,按 Ctrl+B <,输入您选择的标题,窗格标题将被设置。

The rationale to use a different variable

Pane title can be set from multiple sources, and I wanted to avoid any interference with it.

  1. Tmux select-panel-T title1
  2. 使用转义序列字符‘ printf’033]2;% s 033’‘ title 放在这里

档号: https://gist.github.com/ethagnawl/db27bba3c4cccdc30ade2a0c54f49723