When working with terminal multiplexers like tmux, one really annoying problem is the fact that environment variables like
DISPLAY get outdated when reattaching to a session. This means that you can’t connect to the ssh-agent (in the case of
SSH_AUTH_SOCK) or use X forwarding (in the case of
DISPLAY) unless you open up a new pane.
This can interrupt your workflow greatly when using tools like git, which depend on the availability of an ssh-agent, or when trying to access the X clipboard on the remote server.
You might know that updated environment variables can be passed to tmux through the
update-environment setting like this (in
set-option -g update-environment "SSH_AUTH_SOCK \ SSH_CONNECTION \ DISPLAY"
This means that the environment variables will be updated to the correct value when attaching, but only for tmux itself, not for the shells that are running in each pane!
It looks like some way to pass the fresh variables to each opened shell is needed. A lot of people recommend to link the currently active ssh-agent socket to a fixed location from
.bashrc and to set the
SSH_AUTH_SOCK variable to that location. This might solve the issue in the case of ssh, but doesn’t work for X forwarding.
The way I’m solving the problem right now is by updating the two variables each time a new command is executed. This has the benefit that I never have to think about updating variables manually.
.zshrc, I define a
refresh function which gets the fresh environment variables from tmux and exports them:
Note that the function only does something if the current shell is running inside a tmux session.
Then, I define a
preexec hook that calls
refresh before each new command that gets executed:
The same configuration should work for bash.
After setting up tmux and zsh this way, the variables get updated immediately and you never notice that they’ve gone stale.
Check out the rest of my configuration on Github.