【问题标题】:Why am I getting a "failed to connect to server" message from tmux when I try to list sessions?为什么我在尝试列出会话时收到来自 tmux 的“连接服务器失败”消息?
【发布时间】:2012-03-28 22:51:39
【问题描述】:

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

failed to connect to server: Connection refused

这是一个错误吗?我熟悉屏幕;我认为screen -ls 是一个非常有用的功能,因为我可能会开始一个会话并让它运行数周,然后再附加到它。因此,列出当前正在运行的 tmux 会话的能力对我来说非常重要。为什么我知道 tmux 正在运行时,tmux ls 会返回“连接被拒绝”错误?

【问题讨论】:

    标签: linux ssh terminal tmux


    【解决方案1】:

    TL;DR: 尝试向 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]
    

    【讨论】:

    • 这是唯一对我有用的东西。我做了一个愚蠢的事情,即执行 rm -rf tmp/* 删除了 tmux 套接字文件。我一定会记住这个技巧的。
    • 这也解决了我的问题:我更改了 $TMP 的愚蠢默认设置,这意味着 tmux 套接字位于错误的位置。
    • 感谢您的回答,这也解决了我的问题。您能否详细说明这里发生了什么以及为什么需要进行此修复?
    • @Harpe 我不知道,可能是一个不易重现的 tmux 错误。
    • 更容易一次性完成此操作的是:pkill -USR1 -xf tmux(至少如果您使用其普通的 tmux 命令启动 tmux 服务器。)
    【解决方案2】:

    当我没有运行任何会话时,就会发生这种情况。我刚开始使用 tmux,并没有意识到如果您重新启动计算机,您会丢失会话,这让我一开始感到惊讶。

    对于那些有同样想法的人:Restore tmux session after reboot。帖子摘要:使用 shell 脚本构建您的 tmux 会话或创建一个花哨的shell history tracker

    【讨论】:

    • 仅供参考:重新启动后不会保存 tmux 会话,因为它们只是后台进程,将在计算机关闭时结束。
    • 不是一个真正准确的答案,因为 OP 没有说要重新启动,但仍然是一个很好的链接,非常有用的想法和链接。
    • 我提到了重启@DJCrashdummy,因为这就是我遇到问题的方式。也许 OP 重新启动了,或者他们没有重新启动。 SO的答案不必准确。希望对更大的社区有所帮助。
    【解决方案3】:

    如果没有打开会话,您确实会收到此错误。如果没有会话打开,则表示没有 tmux 服务器在运行,因此无法连接到它。

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

    tmux new -s name1
    tmux new -s name2
    

    这些将使用默认套接字名称在服务器上创建 2 个会话。现在你可以这样做了:

    $ 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)。这是我通常做的。

    【讨论】:

      【解决方案4】:

      当 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
      

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

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

      【讨论】:

        【解决方案5】:

        您的.tmux.conf 中可能有错误。在我从.tmux.conf 中取出这条线之前,我遇到了这个问题:

        set-window-option -g xterm-keys on
        

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

        【讨论】:

        • 它在哪里打印日志?应该是控制台输出吗?
        【解决方案6】:

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

        【讨论】:

        • 谢谢,这就是我的解决方案。下一步就是使用tmux new -s $session_name 创建一个新会话,仅此而已。
        【解决方案7】:

        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 的输出,我们都会得到两种情况(忽略pidtmux attach 的更改):

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

        清楚地表明在客户端进程(PID 19229)中键入的命令(在这种情况下为pstree)由服务器一(PID 19231)执行,从而允许它们在没有SIGHUP 的情况下继续执行客户端丢失的事件(例如通过 ssh)。


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

        在这种情况下,解决方案是grep 处理tmux 进程(例如通过ps),并祈祷您没有因为服务器死机而收到此错误(因此您可以通过以下方式附加到它使用lsof 来获取它监听的套接字)。否则,无法附加到服务器,因为它就像重启后一样死机。


        TL;DR:

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

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

        【讨论】:

          【解决方案8】:

          我在 tmux (reattach-to-user-namespace) 中使用了另一个程序,我在切换计算机时收到此错误,因为未安装 reattach-to-user-namespace。解决方法是简单地运行brew install reattach-to-user-namespace

          【讨论】:

            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

              试试tmux -L name1 list-session

              【讨论】:

              • 此命令将只列出name1 会话而不是name2。有关列出多个会话的方法,请参阅 my answer
              • 问题的第一个词是“为什么”。该答案甚至没有尝试提供。另外,在我的情况下,该命令实际上失败了(但是,tmux -L list-session 神奇地起作用了——现在我必须自己去了解为什么,为什么不是前者,如何等等。所以基本上我必须自己回答 OP 的问题)。跨度>
              • @whyisyoung 不幸的是,SO 不允许在几分钟后取消对 cme​​ts 的投票。但是您的评论具有很大的误导性。您对tmux -L list-session 所做的是开始一个新的 tmux 实例,带有一个名为list-session 的套接字。这完全是一种误导,因为命令显示:“使用 tmux 列出带有 -L 标志的会话”。考虑到它的危害性,您应该删除该评论(因为您无法再编辑)。
              • @7heo.tk 对不起,我不记得当时发生了什么。然后我尝试了命令tmux -L list-session,它确实启动了一个新的instance,而不是session。感谢您的评论。
              • @whyisyoung 谢谢你的清理;很高兴看到 SO 的内容随着时间的推移而改进。 (无关:对于阅读上述cmets的人;我为所有人(不仅是我自己)回答了OP的问题here
              猜你喜欢
              • 2018-10-27
              • 2021-12-20
              • 2012-07-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-10-16
              • 1970-01-01
              相关资源
              最近更新 更多