tmux has an interesting quirk in the way it handles environment variables that if you’re not careful can cause some seemingly strange behavior.

Fortunately, this behavior is documented but in my opinion, is not intuitive. From the tmux man page:

When the server is started, tmux copies the environment into the
global environment;
in addition, each session has a session
environment. When a window is created, the session and global
environments are merged. If a variable exists in both, the value
from the session environment is used. The result is the initial
environment passed to the new process.

What this says is that the global environment is copied over when the server is
started. Each session also has an environment that is merged with the original
global environment but it only has a set list of environment variables that are
updated. You can see this with the following command in a tmux session:

> tmux show-environment
-DISPLAY
-KRB5CCNAME
-SSH_AGENT_PID
-SSH_ASKPASS
SSH_AUTH_SOCK
-SSH_CONNECTION
-WINDOWIDkj
-XAUTHORITY

This can cause some interesting consequences when you have multiple named tmux sessions running. Here’s an example of
this in action:

> export FOO=foo
> tmux new-session -t first
> echo $FOO
foo

> export FOO=bar
> tmux new-session -t second
> echo $FOO
foo

As long as the tmux server is running, it will retain the copy of the environment at the moment it was started and
unless the environment variable is in a set list it will not be updated when a new session starts even if its a
completely separate session.

There are a few different ways to work around this. If you know you’ll want a specific environment variable updated each
time you start a new session, you can add the variable to the global update list.

tmux.conf

set-option -g update-environment "FOO"

This will tell tmux the session environment for $FOO whenever a new session is created or an existing session is
attached to.

Alternatively, you can manually update the environment using tmux set-environment this can be applied to either the
global environment so that each new session picks up the new value or for a specific session.

Lastly, you can avoid the problem altogether by providing a named socket to tmux using -L which will cause a new server to start
and copy the current environment into the global environment.

> export FOO=foo
> tmux new-session -t first
> echo $FOO
foo

> export FOO=bar
> tmux -L other new-session -t second
> echo $FOO
bar

This does make the ergonomics for tmux a little more cumbersome since you’ll need to provide the name of the socket
each time you want to run tmux commands. For example, to re-attach to the second session you’ll need to do tmux -L other attach -t second.

Read More