为什么当我尝试列出会话时,会收到来自 tmux 的“未能连接到服务器”消息?

下面是发生在我身上的事情: 我使用 tmux -L name1tmux -L name2启动 tmux 会话; 然后使用 ctrl + B + d分离它们。然后,我尝试获取计算机上当前正在运行的会话的列表。但是,当我运行 tmux ls时,我得到一个错误消息:

failed to connect to server: Connection refused

这是窃听器吗?我熟悉 screen; 我认为 screen -ls是一个非常有用的函数,因为我可能会启动一个会话,并在下次附加到它之前让它运行几个星期。因此,列出当前正在运行的 tmux 会话的能力对我来说非常重要。当我知道 tmux 正在运行时,为什么 tmux ls返回一个“连接拒绝”错误?

70311 次浏览

试试 tmux -L name1 list-session

您的 .tmux.conf可能有错误。我有这个问题,直到我从我的 .tmux.conf中拿出这句话:

set-window-option -g xterm-keys on

您还可以尝试 tmux -v,然后查看它打印的日志。

当我没有运行任何会话时,就会发生这种情况。我刚开始使用 tmux,没有意识到,如果你重新启动你的电脑,你失去了你的会议,这使我感到惊讶,在第一。

对于那些正在考虑同样事情的人: 重新启动后恢复 tmux 会话。这篇文章的摘要: 使用 shell 脚本来构建你的 tmux 会话或者创建一个花哨的 弹壳历史追踪器

我在 tmux 内部使用另一个程序(重新附加到用户名称空间) ,当我切换计算机时遇到了这个错误,因为没有安装重新附加到用户名称空间。修复方法是简单地运行 brew install reattach-to-user-namespace

如果没有打开会话,就会出现这个错误。如果没有会话打开,就没有运行 tmux 服务器,因此它无法连接到它。

使用 -L选项,您可以更改 tmux 服务器使用的套接字名称,这不是为会话命名的一种方式。你最好使用以下命令:

tmux new -s name1
tmux new -s name2

这将在一台服务器上创建两个使用默认套接字名称的会话:

$ tmux ls
name1: 1 windows (created Mon Sep 22 10:34:40 2014) [158x40] (attached)
name2: 1 windows (created Mon Sep 22 10:34:43 2014) [158x40] (attached)

您将看到所有会话都在默认套接字上的服务器上运行。你可以用以下方法重新接上其中一个:

tmux attach -d -s name1

-s指定会话的名称
-d将它从它的前一个客户端分离(如果它是附加的)

您还可以使用 choose-tree命令在 tmux 内部的会话之间切换,该命令默认被分配给按键 C-s(前缀键 + s)。这是我经常做的。

一个简单的修复方法是删除 tmux 服务器留下的 tmp 文件,例如,通过执行 $ rm -rf /tmp/tmux-xxx/

TMUX(1)的工作方式是让客户端进程(tmux)连接到服务器进程(tmux也是,但不连接到 TTY) ,如下面的 ps输出所示:

  PID TTY      STAT   TIME COMMAND
19229 pts/1    S+     0:00 tmux
19231 ?        Ss     0:00 tmux

这表明客户机实际上是在服务器之前启动的(可以假设它是分叉的)。


在分离/重新连接之后,相同的 ps命令输出如下:

  PID TTY      STAT   TIME COMMAND
19231 ?        Ss     0:00 tmux
19290 pts/1    S+     0:00 tmux attach

这将 tmux 客户机显示为 tmux attach,因此更容易理解。


现在,如果我们看看上面两种情况下 pstree的输出,我们会得到这两种情况(忽略 tmux attachpid变化) :

pstree -p
init(1)─┬─acpid(1824)
├─cron(1859)
⋮
├─sh(14146)───tmux(19229)
└─tmux(19231)───sh(19233)───pstree(19234)

清楚地显示在客户端进程(PID 19229)中输入的命令(本例中为 pstree)由服务器执行(PID 19231) ,从而允许它们在客户端丢失(例如,通过 ssh)的情况下在没有 注意的情况下继续执行。


现在,回到 OP 提出的问题: 在 tmux返回 failed to connect to server: Connection refused的情况下会发生什么,无论出于什么原因(可能是因为服务器进程死亡; 也可能是因为执行 tmux客户端的用户没有访问 tmux 套接字的权限,等等) ,服务器进程(在我们的例子中是 pid 19231)是不可访问的

在这种情况下,解决方案是对 tmux进程使用 grep(例如通过 ps) ,并祈祷您没有得到这个错误,因为服务器已经死亡(因此您可以通过使用 lsof来获取它所监听的套接字)。否则,就无法将 接上连接到服务器,因为它就像重启后一样死机。


译者:

这个错误可能有多种原因,从错误到严重失败(程序死亡)。简而言之,使用您可以使用的 UNIX 工具来确定 tmux使用哪个套接字,它是否仍在运行(如果您的 tmux 客户机正在运行,那么应该至少有两个进程——这是在从 shell 调用 tmuxtmux attach之后发生的) ,因此如果您丢失了会话,还是没有丢失会话。

注意: 正如其他答案所指出的,如果显示此错误的原因是套接字错误,则可以使用 -L标志告诉 tmux使用特定的套接字。

这发生在我的 Ubuntu 桌面崩溃和我的 gnome 终端窗口退出时。我仍然可以看到 tmux 进程正在运行(ps aux | grep tmux) ,但由于某些原因,tmux 命令无法列出现有的会话。显然,它没有找到仍在运行的 tmux 进程的现有 Unix 套接字。这个场景中的补丁是找到现有的 Unix 套接字,并使用 -S标志指定为 tmux; 下面是方法:

您可以通过以下方法找到仍在运行的 tmux 进程的 PID:

ps -p $(pidof tmux)

现在拿出你的 PID (在我的例子中是6876) ,运行它来列出所有打开的 Unix 套接字:

sudo lsof -Uap 6876

希望您能看到这样的输出:

COMMAND  PID USER   FD   TYPE             DEVICE SIZE/OFF   NODE NAME
tmux    6876  abe    3u  unix 0x0000000000000000      0t0 408477 socket
tmux    6876  abe    4u  unix 0x0000000000000000      0t0 408478 socket
tmux    6876  abe    6u  unix 0x0000000000000000      0t0 408479 /tmp/tmux-1000/default

现在,您可以指定现有的 Unix 套接字到您的 tmux 命令(使用 -S标志) ,您应该能够列出会话并正确地附加:

tmux -S /tmp/tmux-1000/default list-sessions
tmux -S /tmp/tmux-1000/default attach -t 0

如果您或任何清理过程删除 /tmp/*中的文件,都可能发生这种情况。如果无法恢复这些文件,则所有会话数据都将丢失。不幸的是,杀死所有 tmux 实例并重新启动它是唯一的选择。

尝试向 tmux 服务器进程发送 SIGUSR1信号。

就我而言,在8天的不运动后,我无法重新接上:

$ tmux attach
no sessions

然而,一个用于 tmux 进程的 grep 得到了以下输出:

$ ps -aef | fgrep -i tmux
hari     7139     1  1  2016 ?        2-20:32:31 tmux
hari    25943 25113  0 22:00 pts/0    00:00:00 fgrep --color=auto -i tmux

正如@7heo 所建议的那样。Tk,这表明 tmux 服务器仍在运行,但是 tmux ls给出了 failed to connect to server: Connection refused错误。我验证了属于 tmux 会话的 tmp 目录的存在,并且 lsof -p 7139(tmux 服务器的 pid)显示套接字文件是打开的:

COMMAND  PID  USER   FD   TYPE             DEVICE SIZE/OFF       NODE NAME
tmux    7139 hari    5u  unix 0x0000000000000000      0t0 1712879255 /tmp/tmux-50440/default

我还尝试显式地将 -S /tmp/tmux-50440/default指定为 tmux,但它没有帮助。但是,我在 tmux 手册页中读到,发送 SIGUSR1将使 tmux 重新创建套接字文件,因此我尝试了这种方法,并能够立即找到会话并重新连接:

$ kill -s USR1 7139
$ tmux ls
0: 12 windows (created Mon Apr 18 21:17:55 2016) [198x62]

This happened to me because I ran tmux with another user (was root), and I tried to list sessions with my normal user.. 因此,您可能需要检查首先运行 tmux 的用户。 这样做:

$ ps -aef | fgrep -i tmux
root     7139     1  1  2016 ?        2-20:32:31 tmux
centos    25943 25113  0 22:00 pts/0    00:00:00 fgrep --color=auto -i tmux

请看第一列中的用户名: 这里是 root