3

我想知道是否有任何简单的方法可以更改 bash 环境变量并在 tmux 会话中应用于 Windows?

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

谢谢!!

4

3 回答 3

4

您不能直接更改环境变量。

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

首先,tmux 可以自己更新环境变量。update-environment配置指令执行此操作。此处列出的任何变量都将自动更新 - 连接到 tmux 会话会使用您刚刚连接的客户端的值更新会话的环境变量。因此,如果您运行tmux attachSSH_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。但是,您需要单独配置您可能想要使用的每个程序。

于 2014-05-21T19:07:16.717 回答
3

不。

甚至没有困难的方法;操纵另一个进程的环境变量充其量是不可移植的。

于 2012-03-28T05:35:27.660 回答
1

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

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

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

更好的是,我们还可以更新环境,甚至在 windows 自己的 tmux 会话中:

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

有关标志的完整说明,请参阅tmux 手册页

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


这是我的用例:

通过设置 shell 配置的方式,我将环境导出到登录 shell,然后执行到 tmux 会话中。我认为由于环境变量不经常更改,我不需要每次都在新的非登录 shell 中获取它们。但是,当它们发生更改时,我不想重新启动整个 tmux 会话以让新的 tmux 窗口知道更改。虽然使用该update-environment选项并重新连接解决了会话重启问题,但在我的 tmux 配置中维护一个潜在可延展环境变量的显式列表很麻烦。

使用以下函数,我们可以更新我们的环境变量,~/.shenv例如,而不是获取文件 ( . ~/.shenv),我们可以提升文件 ( promote ~/.shenv) 以便新的 tmux 窗口从这个更新的环境继承。

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

这里发生的事情是我们从一个空环境(除了HOME我们添加的)的外壳中获取我们的文件,并打印出我们的新环境变量。我们通过管道将它们放入 acut以提取每一行的变量,并将其存储在一个名为 的变量中var。在一些元魔术eval从当前 shell 中获取该变量的间接值之后,我们更新了我们的 tmux 目标会话。在这种情况下,local是我们的 tmux 会话的名称。

于 2020-05-19T02:48:15.250 回答