如何更改环境变量并应用于tmux会话中的所有窗口

时间:2012-03-28 05:32:57

标签: tmux

我想知道有什么简单的方法可以更改bash环境变量并应用于tmux会话中的窗口吗?

我用Google搜索并没有找到解决方案,所以我在这里发布了这个问题。

谢谢!

3 个答案:

答案 0 :(得分:4)

您无法直接更改环境变量。

但是,您可以在tmux实例中创建shell终端来获取新变量。这需要几个步骤。

首先,tmux可以自行更新环境变量。 update-environment配置指令执行此操作。此处列出的任何变量都将自动更新 - 连接到tmux会话会使用您刚刚连接的客户端的值更新会话的环境变量。因此,如果您运行tmux attach并设置了SSH_AUTH_SOCK,那么tmux会话将获得SSH_AUTH_SOCK的新值。

但是,这只会更新会话的变量,因此只有新的窗格/窗口才能获取值。现有窗口仍将具有旧值。正如@ IgnacioVazquez-Abrams所说,没有直接的解决方法。

但是,您可以在许多程序中修复它。最新版本的tmux具有show-environment命令,该命令在会话中查询环境变量的当前值。这允许您在使用update-environment逻辑后从程序中获取环境变量。

例如,您可以让一些shell获取新值。在ZSH中,我使用precmd中的~/.zshrc钩子执行此操作:

_update_ssh_agent() {
    local var
    var=$(tmux show-environment |grep '^SSH_AUTH_SOCK=')
    if [ "$?" -eq 0 ]; then
        eval "$var"
    fi
}
if [[ -n "$TMUX" ]]; then
    add-zsh-hook precmd _update_ssh_agent
fi

这使得tmux会话中的shell在每次显示新提示时都会更新SSH代理。重新连接后,我所要做的就是在提示时按Enter键,它会抓取新的SSH代理连接。

Bash也有一个预命令机制,虽然我不知道如何配置它。您还可以配置更多程序以使用show-environment更新自己,例如vim或emacs。但是,您需要单独配置您可能想要执行此操作的每个程序。

答案 1 :(得分:3)

没有

甚至没有一个艰难的道路;操纵另一个进程的环境变量最多是不可移植的。

答案 2 :(得分:0)

这是一个古老的问题,但是当我搜索我想做的事情时出现了,所以这是另一个解决方案。

启动tmux时,它将环境复制到全局环境中。创建新窗口时,它将合并全局环境和会话环境以设置该窗口的环境。我们可以通过以下方式查看这些环境:

tmux show-environment [-g] [-t target-session]

更好的是,即使在Windows自己的tmux会话中,我们也可以更新环境:

tmux set-environment [-gru] [-t target-session] name [value]

有关标志的完整说明,请参见tmux man page

此功能正是我想要的。不幸的是,它不会更新现有shell的环境,但是我们可以轻松地遍历tmux showenv -g以重新导出可能由另一个进程设置的tmux环境。


这是我的用例:

通过设置shell配置的方式,我将环境导出到登录shell中,然后执行到tmux会话中。我认为由于env var不会经常更改,因此我不需要每次都在新的非登录shell中提供它们。但是,当它们确实发生更改时,我不想重新启动整个tmux会话,以使新的tmux窗口知道更改。在使用update-environment选项并重新连接可以解决会话重新启动的同时,在我的tmux配置中维护显式的可扩展env变量的清单很麻烦。

使用以下功能,我们可以以类似~/.shenv的方式更新环境变量,并且可以 promote 而不是采购文件(. ~/.shenv)。文件(promote ~/.shenv),以便新的tmux窗口从此更新的环境继承。

promote() {
    sourced="$1"; shift
    . "$sourced"
    env - \
        "HOME=$HOME" \
        "SHELL=$SHELL" \
        | sh -c ". $sourced; env" | while read -r line; do
            arg="$(echo "$line" | cut -d= -f1)"
            val="$(echo "$line" | cut -d= -f2-)"
            tmux set-environment -gt local "$arg" "$val"
        done
}