我在使用多个 tmux 会话时注意到了一些奇怪的事情。我不确定所有的术语,所以如果我错了,请纠正我。
创建第一个之后的 tmux 会话不会继承创建它的环境,而是继承产生第一个会话的环境。
export a=false; export b=false
bash
export a=true
tmux new-session -d -s first
bash
export b=true
tmux new-session -d -s second
然后从任一会话执行echo $a $b
都会给出输出true false
。我期望true true
第二个会话。
我不知道 tmux 如何“记住”第一个会话的环境。我可以再做一次实验:
如果我在第一个会话中更新环境,分离并生成第二个会话,则第二个会话不会继承该更新。
另一个实验:
如果我在创建第一个会话后退出子 shell(从而“忘记”环境变量a
),并生成第二个会话,则第二个会话仍然会记住环境。
我想更好地了解为什么会发生这种情况以及 tmux 在幕后做了什么,因此,任何这方面的建议都将不胜感激。
答案1
有一个名为的ENVIRONMENT
部分man 1 tmux
:
当服务器启动时,
tmux
将环境复制到全局环境中;此外,每个会话都有一个会话环境。当创建窗口时,会话和全局环境将合并。如果变量存在于两者中,则使用来自会话环境的值。结果是传递给新进程的初始环境。当创建新会话或重新连接旧会话时,可以使用会话
update-environment
选项从客户端更新会话环境。[…]改变和查看环境的命令是:
set-environment
[…]
show-environment
[…]
手册中解释set-option
道:
update-environment variables
设置一个以空格分隔的字符串,其中包含在创建新会话或附加现有会话时要复制到会话环境中的环境变量列表。
[…] 默认是
"DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY"
。
因此,您的a
和仅在服务器启动时才会b
被复制到。就您而言,这是在您创建会话时。这些变量不在选项存储的列表中,因此稍后不会更新它们。tmux
first
update-environment
如果你这样做
tmux set-option -t second update-environment "a b"
然后附加到此会话,您的当前变量将被 吸收tmux
。这并不意味着echo $a $b
会在已启动的 shell 中显示它们(由 启动tmux new-session -d -s first
)。但新窗格中的新 shell(或任何其他进程)将从 继承它们tmux
。
可以全局设置该选项。请参阅相关OPTIONS
部分。但请记住以下几点:
- 该选项旨在在创建新会话或重新连接的旧
-E
(尽管您可以使用选项改变行为attach-session
;其他一些命令也支持-E
); - 更新后的值不会影响现有流程(窗格)。
总结一下:一般来说,tmux
会话和进程不会像简单的子进程那样简单地从客户端继承环境。