我可以作为gnome-session的孩子启动tmux吗?

时间:2013-01-29 12:53:31

标签: gnome tmux

我正在运行Ubuntu并使用gnome-terminal并希望以这样的方式运行tmux,它可以像打开新终端一样使用所有gnome-session环境窗口会。例如。使用passphrase-less ssh。

问题似乎是流程层次......

gnome-terminal的新窗口中:

$ pstree -ps $$
init(1)───lightdm(1825)───lightdm(18486)───gnome-session(18552)───gnome-terminal(18626)

进入 tmux会话后(即使在上面的终端窗口中:

$ pstree -ps $$
init(1)───tmux(15798)───bash(21770)

tmux似乎是init的直接子节点,而不是会话的进程层次结构。有没有办法让它成为gnome-session的孩子?

编辑:以下很棒的答案(已接受的答案)!但是,我认为自从收到将tmux的所有子bash进程更新到最新环境的答案后,我会添加一个我写的函数:

#!/bin/bash

tmup () 
{ 
    echo -n "Updating to latest tmux environment...";
    export IFS=",";
    for line in $(tmux showenv -t $(tmux display -p "#S") | tr "\n" ",");
    do
        if [[ $line == -* ]]; then
            unset $(echo $line | cut -c2-);
        else
            export $line;
        fi;
    done;
    unset IFS;
    echo "Done"
}

1 个答案:

答案 0 :(得分:4)

tmux 服务器调用守护程序(3)以从启动它的进程(即初始 tmux 客户端)中分离出来。这不是可选的,因此在守护程序(3)完成双叉和中间退出之后,服务器将始终重新定位到PID 1(例如 init )。

一般情况下, tmux 服务器不再直接“连接”到 gnome-session ,尽管是(幸存的)进程的亲子关系,这一点并不重要。 / p>

对于 ssh ,无需重新键入其密码即可使用密钥依赖于对 ssh-agent 进程的访问。 ssh 的实例查找SSH_AUTH_SOCK环境变量,以了解可以为其提供密钥的 ssh-agent 的联系方式。 gnome-session 可能会安排启动 ssh-agent 并使用适当的SSH_AUTH_SOCK值填充其环境。当您的各种进程启动时,此环境将从父级继承到子级。通过这种方式, tmux 服务器也将继承SSH_AUTH_SOCK值(来自最初的 tmux 客户端,它从shell获取它,从 gnome-获取它终端,它来自 gnome-session )。

但是,当您连接到从其他环境启动的 tmux 会话时,会出现问题。请考虑以下情况,即 tmux 服务器的PID低于 gnome-session 的PID:

  1. 登录GUI会话 gnome-session 启动 ssh-agent 并在其环境中配置SSH_AUTH_SOCK=foo;这个值将被所有未来的孩子继承。
  2. 启动 tmux 服务器(通过shell和 gnome-terminal )。
    tmux 服务器继承SSH_AUTH_SOCK=foo;它将被传递给它的子节点(例如,在 tmux 会话中运行的shell)。
  3. 您与 tmux 会话断开连接并退出GUI会话 tmux 服务器及其子服务器仍然有SSH_AUTH_SOCK=foo,但该值可能不再有效(当 gnome-session 正在逐渐减少时,它可能会杀死< em> ssh-agent 它开始了。)
  4. 稍后,您将重新登录GUI会话 这次 gnome-session 设置SSH_AUTH_SOCK=bar并将其传递给其子女。
  5. 您重新连接到 tmux 会话 此时,您在会话内部SSH_AUTH_SOCK=bar“外部” tmux 和“{1}}”。这可能是你遇到问题的地方。
  6. 实际上,由于 tmux 服务器已经超过原始GUI会话,因此它最初继承的特定于该会话的任何环境变量都可能无效(除非它们恰好在下一个使用完全相同的值你登录GUI会话的时间。)

    幸运的是, tmux 具有处理此方案的功能。 SSH_AUTH_SOCK=foo会话选项指定在客户端创建或附加到会话时复制到(或从“会话环境”中删除)的环境变量的列表。 SSH_AUTH_SOCK是此选项的默认值的一部分,因此在重新附加时会更新它。但是, tmux 只能更新其“会话环境”(将由该会话的任何子级继承)。

    不幸的是, tmux 无法更新属于该会话的任何现有进程(实际上,这是不可能的,缺少可以修改的调试工具已经运行的进程的内部)。因此,在上述场景之后在Windows /窗格中运行的任何现有shell都可能使用无效的SSH_AUTH_SOCK。 ssh 不会抱怨无效值,它只会提示您输入相应密钥的密码。

    您可能尝试做的是从会话环境中提取SSH_AUTH_SOCK的值,并使用以下命令将其合并到旧会话中的预先存在的shell中:

    update-environment

    如果您遇到与其他环境变量相关的问题,则可能需要将其添加到 SSH_AUTH_SOCK=$(tmux show-environment | awk '/^SSH_AUTH_SOCK=/ { sub(/.*=/,""); print }') (例如update-environment中的set-option -ga update-environment ' FROBNIZ')并执行类似操作以复制值从不同的上下文中重新附加到任何现有的shell中。