tmux update-environment

tmux is one of the tools I use everyday. But one thing always annoyed me: even though I am using X11 forwarding and ssh-agent forwarding when re-attaching to a session, the DISPLAY and SSH_AUTH_SOCK environment variables are often wrong. Environment variables are initialized only once when the window was created. tmux is able to update some environment variables for new windows and panes based on the update-environment setting, however, existing shell windows cannot be updated.

Therefore I wrote a little wrapper around tmux for the bash shell. This adds a new command tmux update-environment that updates the environment variables from the current session environment:

function tmux() {
    local tmux=$(type -fp tmux)
    case "$1" in
        update-environment|update-env|env-update)
            local v
            while read v; do
                if [[ $v == -* ]]; then
                    unset ${v/#-/}
                else
                    # Add quotes around the argument
                    v=${v/=/=\"}
                    v=${v/%/\"}
                    eval export $v
                fi
            done < <(tmux show-environment)
            ;;
        *)
            $tmux "$@"
            ;;
    esac
}

So now when I encounter the error Can't open display from any program trying to open a window, I only need to type tmux update-environment to get the new DISPLAY environment variable for the shell.

You can also get the full file with an additional reorder-windows command as a download. This file is meant to be sourced from your .bashrc. You can share and use this script as you will, it is hereby placed into Public Domain.

6 thoughts on “tmux update-environment

  1. Yong-Chull

    Great! This script fixes my problem with the variable $DISPLAY. Thanks 😉

  2. Sho-Zee

    I should have read this post much earlier! Very helpful. Many thanks!

  3. Cam

    Very similar to what I have done:

    tmuxenv() {
    eval $(tmux show-environment | sed -e ‘/^-/d’ -e “s/’/’\\\\”/g” -e “s/=\(.*\)/=’\\1’/”)
    }

  4. Ryan

    This is great! I wish there was a way to automate this behavior, especially now that recent versions of tmux support hooks:

    set-hook -g client-attached “run-shell ‘…'”

    but unfortunately, it looks like run-shell operates in a sub-shell, so anything that happens there doesn’t affect the environment variables of the windows/panes inside the session. 🙁

  5. Rainer Müller Post author

    Indeed, it needs to be done in the shell itself as the environment can only be updated from within the same process. That is why I implemented it as a shell function. Then putting it in a wrapper around ‘tmux’ itself is just syntactic sugar.

    tmux already automatically updates the environment variables when you attach to a session (see the update-environment option), but that will only apply to new windows/panes as the environment is copied to the new shell process on fork().

Leave a Reply

Your email address will not be published. Required fields are marked *

*