tmux environment variable sync¶
Introduction¶
How to automatically (un)set environment variables when attaching a tmux session.
Whenever possible, I avoid SSH agent forwarding and instead rely on ProxyJump
if I need to
connect to a host via a bastion host. However, sometimes I want to expose my local SSH agent to a
remote host so I can clone a Git repo directly onto that host.
This can be a pain for tmux users because the remote host looks for the (forwarded) SSH agent
via the SSH_AUTH_SOCK
environment variable, which will not be set or updated when attaching an
existing tmux session created in a previous SSH session.
There are plenty of workarounds to be found online, but years ago I was faced with this issue and wanted to implement a more generic solution that would suffice for any environment variable I specify.
In short, I do the following:
-
Before attaching a tmux session, update the specified environment variables in tmux' global environment to reflect their state in the current shell environment.
-
After attaching a tmux session, update the specified environment variables in the current shell environment to reflect their state in tmux' global environment.
Here are the relevant snippets from .tmux.conf
and .zshrc
.
~/.tmux.conf
¶
# https://www.mankier.com/1/tmux#Options
# https://www.mankier.com/1/tmux#Global_and_Session_Environment
set-option -g update-environment \
'DISPLAY KRB5CCNAME SSH_AGENT_PID SSH_ASKPASS SSH_AUTH_SOCK SSH_CLIENT SSH_CONNECTION SSH_TTY \
SSH_USER_AUTH WINDOWID XAUTHORITY'
~/.zshrc
¶
tm() {
local SESSION_NAME
if [[ -v 1 ]]; then
SESSION_NAME="${1}"
else
SESSION_NAME=default
fi
tmux new-session -AD -s "${SESSION_NAME}"
}
tmux_global_update_var() {
local VAR="${1}"
local VALUE
if [[ -v 2 ]]; then
VALUE="${2}"
elif [[ -v "${VAR}" ]]; then
VALUE="${(P)VAR}"
else
tmux set-environment -gru -- "${VAR}"
return
fi
tmux set-environment -g -- "${VAR}" "${VALUE}"
}
tmux_shell_update_var() {
local VAR="${1}"
local TMUX_OUTPUT
local TMUX_ERROR_CODE
TMUX_OUTPUT="$(tmux show-environment -gs -- "${VAR}" 2> /dev/null)"
TMUX_ERROR_CODE="${?}"
if [[ "${TMUX_ERROR_CODE}" -eq 0 ]]; then
eval -- "${TMUX_OUTPUT}"
else
unset -- "${VAR}"
fi
}
tmux_update_environment() {
if ! whence -p -- tmux > /dev/null; then
return
fi
local IFS=$'\n'
local FUNC
local VAR
local VARS
if [[ ! -v TMUX ]]; then
if ! tmux has-session 2> /dev/null; then
return
fi
FUNC=tmux_global_update_var
else
FUNC=tmux_shell_update_var
fi
VARS=($(tmux show-options -gv -- update-environment))
for VAR in "${VARS[@]}"; do
eval -- "${FUNC}" "${VAR}"
done
}
# https://zsh.sourceforge.io/Doc/Release/Functions.html#index-preexec
preexec() {
tmux_update_environment
}