我想知道是否有任何简单的方法可以更改 bash 环境变量并在 tmux 会话中应用于 Windows?
我用谷歌搜索并没有找到解决方案,所以我在这里发布了这个问题。
谢谢!!
您不能直接更改环境变量。
但是,您可以让 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。但是,您需要单独配置您可能想要使用的每个程序。
不。
甚至没有困难的方法;操纵另一个进程的环境变量充其量是不可移植的。
所以这是一个老问题,但是当我在寻找我想做的事情时出现了,所以这是另一个解决方案。
当 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 会话的名称。