在我的本地机器上,我有 3 个 node.js 实例同时运行。每个在名为“服务器”的 tmux 窗口中都有自己的窗格。问题是要弄清楚哪个节点在哪个窗格中运行并不容易,因为它们的日志是相似的。
我需要的是每个窗格的标题。正如我所知道的,tmux 本身没有这个功能:它只有窗口的标题,而不是窗格的标题。在每个 node.js 实例的每个窗格中启动单独的 tmux 会话看起来有点过头了。
那么是否有一些小程序可以启动命令,用指定的状态栏包装其输出?
提前致谢
在我的本地机器上,我有 3 个 node.js 实例同时运行。每个在名为“服务器”的 tmux 窗口中都有自己的窗格。问题是要弄清楚哪个节点在哪个窗格中运行并不容易,因为它们的日志是相似的。
我需要的是每个窗格的标题。正如我所知道的,tmux 本身没有这个功能:它只有窗口的标题,而不是窗格的标题。在每个 node.js 实例的每个窗格中启动单独的 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;
您可以使用转义序列 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。
在外部终端。
像tmux和screen这样的程序就是这样的终端重新模拟器。当然,终端仿真器还包含许多其他功能,但您需要大量终端仿真代码才能提供可靠的状态行。
但是,有一个轻量级的解决方案,只要
与许多终端仿真器一样,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之外工作。csr
cup
因为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
我使用的是 tmux 2.3 版,我认为以前的版本不支持边框样式。这对我有用:
为每个窗格设置标题:
printf '\033]2;My Pane Title\033\\'
然后:
tmux set -g pane-border-format "#{pane_index} #T"
我正在处理 tmux - ticket 的窗格状态栏。我的开发分支可以在 github 上找到: https ://github.com/jonathanslenders/tmux
现在,这已经添加了一个有效的重命名窗格“标题”命令。还有一些bug,API会改进的。这个想法是为每个窗格创建一个状态栏,它可以有一些格式,比如会话状态栏。像 tmux 的其余部分一样,一切都应该成为可编写脚本和可定制的。完成并稳定后,它可能会包含在官方 tmux 中。
是的,有这样一个命令:tmux
. 为您的会话命名,它将显示在内部状态栏中:
TMUX=0 tmux new-session -s my-new-session
这在短期内没有帮助,但是在 tmux 中有一个针对每个窗格标题的功能请求:http: //sourceforge.net/tracker/ ?func=detail&aid=3495916&group_id=200378&atid=973265#
与此同时,正如其他人所提到的,嵌套 tmux 工作得很好。
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://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}\""