103

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

我需要的是每个窗格的标题。正如我所知道的,tmux 本身没有这个功能:它只有窗口的标题,而不是窗格的标题。在每个 node.js 实例的每个窗格中启动单独的 tmux 会话看起来有点过头了。

那么是否有一些小程序可以启动命令,用指定的状态栏包装其输出?

提前致谢

4

10 回答 10

92

此功能已在本次提交中添加到 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}"
于 2016-06-02T21:02:26.553 回答
89

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

]2;您可以使用转义序列 ESC ... ESC设置窗格的标题(例如,请参阅tmux 手册页中\名为Names and Titles的部分)。您可以像这样从 shell 执行此操作:

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

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

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


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

在一般情况下,要在某个给定终端上提供不可侵犯的状态行,您将需要一个完整的终端(重新)仿真器,它位于原始终端和新终端(一个少一行)之间。需要这种(重新)仿真来转换发送到内部终端的控制序列并将它们转换为原始终端。例如,要在外部终端的底部保持状态行,命令

移动到最后一行。

发送到内部终端必须成为

移动到倒数第二行。

当翻译并发送到外部终端时。同样,发送到内部终端的 LF 必须变为

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

在外部终端。

tmuxscreen这样的程序就是这样的终端重新模拟器。当然,终端仿真器还包含许多其他功能,但您需要大量终端仿真代码才能提供可靠的状态行。


但是,有一个轻量级的解决方案,只要

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

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

限制(不允许光标移动命令,不允许调整大小)是必需的,因为生成输出的程序(例如Node.js实例)不知道滚动已被限制到特定区域。如果输出生成程序碰巧将光标移到滚动区域之外,那么输出可能会出现乱码。同样,终端模拟器可能会在调整终端大小时自动重置滚动区域(因此“非滚动线”可能最终会滚动出去)。

我编写了一个脚本,用于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'

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

于 2012-03-18T09:00:12.690 回答
52

因为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
于 2019-04-25T09:25:23.323 回答
19

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

为每个窗格设置标题:

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

然后:

tmux set -g pane-border-format "#{pane_index} #T"
于 2017-01-24T03:33:23.123 回答
15

我正在处理 tmux - ticket 的窗格状态栏。我的开发分支可以在 github 上找到: https ://github.com/jonathanslenders/tmux

现在,这已经添加了一个有效的重命名窗格“标题”命令。还有一些bug,API会改进的。这个想法是为每个窗格创建一个状态栏,它可以有一些格式,比如会话状态栏。像 tmux 的其余部分一样,一切都应该成为可编写脚本和可定制的。完成并稳定后,它可能会包含在官方 tmux 中。

于 2013-04-12T10:01:35.007 回答
13

一个 gif 胜过一千个字。(来源

tmux-xpanes是一个基于 tmux 的终端分隔符,支持通过新增-t选项显示每个窗格的标题。

于 2018-07-06T02:49:23.940 回答
7

是的,有这样一个命令:tmux. 为您的会话命名,它将显示在内部状态栏中:

TMUX=0 tmux new-session -s my-new-session
于 2012-03-17T16:41:41.987 回答
4

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

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

于 2012-10-19T21:05:40.883 回答
3

TL;博士

将以下配置附加到您的 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

好好享受

感谢https://stackoverflow.com/a/37602055/5121972

于 2020-07-27T07:53:03.753 回答
0

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

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)\""

这将更改"localhost"时钟旁边右下角的状态栏,因为 pane_title 是所使用的,而它又默认为主机名:

% 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}\""
于 2021-09-27T04:04:30.883 回答