我想知道有什么简单的方法可以更改bash环境变量并应用于tmux会话中的窗口吗?
我用Google搜索并没有找到解决方案,所以我在这里发布了这个问题。
谢谢!
答案 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
}