74

I like to keep my bash_profile in a git repository and clone it to whatever machines I have shell access to. Since I'm in tmux most of the time I have a user@host string in the status line, rather than its traditional spot in the shell prompt.

Not all sites I use have tmux installed, though, or I may not always be using it. I'd like to detect when I'm not in a tmux session and adjust my prompt accordingly. So far my half-baked solution in .bash_profile looks something like this:

_display_host_unless_in_tmux_session() {
    # ???
}
export PROMPT_COMMAND='PS1=$(_display_host_unless_in_tmux_session)${REST_OF_PROMPT}'

(Checking every time probably isn't the best approach, so I'm open to suggestions for a better way of doing this. Bash scripting is not my forte.)

Brant
  • 845

5 Answers5

98

Tmux sets the TMUX environment variable in tmux sessions, and sets TERM to screen. This isn't a 100% reliable indicator (for example, you can't easily tell if you're running screen inside tmux or tmux inside screen), but it should be good enough in practice.

if ! { [ "$TERM" = "screen" ] && [ -n "$TMUX" ]; } then
  PS1="@$HOSTNAME $PS1"
fi

If you need to integrate that in a complex prompt set via PROMPT_COMMAND (which is a bash setting, by the way, so shouldn't be exported):

if [ "$TERM" = "screen" ] && [ -n "$TMUX" ]; then
  PS1_HOSTNAME=
else
  PS1_HOSTNAME="@$HOSTNAME"
fi
PROMPT_COMMAND='PS1="$PS1_HOSTNAME…"'

If you ever need to test whether tmux is installed:

if type tmux >/dev/null 2>/dev/null; then
  # you can start tmux if you want
fi

By the way, this should all go into ~/.bashrc, not ~/.bash_profile (see Difference between .bashrc and .bash_profile). ~/.bashrc is run in every bash instance and contains shell customizations such as prompts and aliases. ~/.bash_profile is run when you log in (if your login shell is bash). Oddly, bash doesn't read ~/.bashrc in login shells, so your ~/.bash_profile should contain

case $- in *i*) . ~/.bashrc;; esac
  • 1
    There is an alternative variable TMUX_PANE as well. I only noticed because your recipe didn't work. Later I found out that I had unduly used (and subsequently unset) a variable in a shell script I am sourcing through my .profile. – 0xC0000022L Jun 02 '14 at 23:23
  • [ "$TERM" = "screen" ] may not work. In my case, my screen was reporting as screen-256 color. – StevieD Apr 07 '19 at 13:59
  • @StevieD I don't think tmux does this on its own, but it might be a distribution patch or configuration. – Gilles 'SO- stop being evil' Apr 07 '19 at 22:55
  • $TMUX and $TMUX_PANE don't mean "in a tmux session", they just mean they exist, if you run a terminal running with tmux, open another terminal running without tmux, check their values in second terminal, they still exist. – CodyChan Sep 11 '20 at 06:38
  • My TERM var is a reflection of what's in my tmux config. In my case set -g default-terminal "tmux-256color", so TERM=tmux-256color is what is set in my env. – oalders Nov 11 '21 at 20:52
  • tmux and tmux-256color has been added to terminfo. Nowadays $TERM in tmux should be one of these two, not screen, not screen-256color. Still one can use something else with tmux command set -g default-terminal …. – Kamil Maciorowski Jul 12 '23 at 05:20
7

As for previous answers, testing the ${TERM} variable could lead to corner cases, tmux sets environment variables within its own life:

$ env|grep -i tmux
TMUX=/tmp/tmux-1000/default,4199,5
TMUX_PANE=%9
TMUX_PLUGIN_MANAGER_PATH=/home/imil/.tmux/plugins/

In order to check if you're inside a tmux environment, simply check:

$ [ -z "${TMUX}" ] && echo "not in tmux"

iMil
  • 389
7

If you're running tmux release 3.2 or later (or using OpenBSD 6.8 or later, or built tmux from sources newer than May 16 2020), you may use the TERM_PROGRAM environment variable.

if [ "$TERM_PROGRAM" = tmux ]; then
  echo 'In tmux'
else
  echo 'Not in tmux'
fi

Earlier releases of tmux does not have this environment variable.

Kusalananda
  • 333,661
gotbletu
  • 156
4

After trying different ways, this is what ultimately worked for me, in case it helps anyone out there:

if [[ "$TERM" =~ "screen".* ]]; then
  echo "We are in TMUX!"
else
  echo "We are not in TMUX :/  Let's get in!"
  # Launches tmux in a session called 'base'.
  tmux attach -t base || tmux new -s base
fi

In this code snippet, I check to see if we're not in TMUX environment, I launch it. If you put this code snippet in your .bashrc file, you will automatically run TMUX anytime you open terminal! P.S.: tested on Ubuntu shell.

Alexar
  • 737
1

Sometimes you may not have access to $TMUX, and $TERM is certainly not reliable. Then, you can compare window ids: the one obtained from tmux itself, and the one you can get from xdotool:

if [ $(tmux showenv | awk -v FS='=' '/WINDOWID/{print $2}') \
     -eq \
     $(xdotool getactivewindow) ]
then
    echo "This terminal is running tmux!"
fi
A S
  • 210