54

Summary

When I create a new tmux session, my prompt pulls from a default bash configuration and I have to manually run source ~/.bashrc for my customized prompt.

Analysis

I am using a RHEL 7 machine. I began noticing this behavior after a bash update a while back, but haven't gotten around to asking the question until now (and am not sure which update this began happening around).

For example, I've customized my prompt to look like:

[user@hostname ~]$

Whenever I start a new tmux session, it uses what appears to be the bash default:

-sh-4.2$

A quick run of source ~/.bashrc always fixes the issue, but it's annoying that I have to do this every time I want to fix something small. Any ideas on how to get tmux to do this automatically again?

If any more information is needed, I am happy to provide.

tmux.conf

For reference, I have my tmux.conf file below, although it is hardly what you could call custom.

setw -g mode-keys vi

# reload tmux.conf
bind r source-file ~/.tmux.conf \; display-message " ✱ ~/.tmux.conf is reloaded"
J.W.F.
  • 1,248

6 Answers6

55

This is related to the Bash init files. By default, ~/.bashrc is used in an interactive, non-login shell. It won't be sourced in a login shell. Tmux uses a login shell by default. Hence, shells started by tmux skip ~/.bashrc.

default-command shell-command

The default is an empty string, which instructs tmux to create a login shell using the value of the default-shell option.

Init files for Bash,

  1. login mode:
    1. /etc/profile
    2. ~/.bash_profile, ~/.bash_login, ~/.profile (only first one that exists)
  2. interactive non-login:
    1. /etc/bash.bashrc (some Linux; not on Mac OS X)
    2. ~/.bashrc
  3. non-interactive:
    1. source file in $BASH_ENV

Solution

The weird interactive, non-login loading requirement confuses people in other situations as well. The best solution is to change the loading requirement of ~/.bashrc as interactive only, which is exactly what some distros, like Ubuntu, are doing.

# write content below into ~/.profile, or ~/.bash_profile

if running bash

if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi

This should be the solution you desire. And I recommend every Bash user setup this in the profile.


Update: the above settings is copied from Ubuntu. It seems they choose to load .bashrc in a login shell no matter it's within an interactive shell or not.

If you wanna detect an interactive shell, use $PS1.

if [ -n "$BASH_VERSION" -a -n "$PS1" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

References

Simba
  • 1,682
  • 1
    This answer gave me the solution while the accepted one did not. – Javier Feb 26 '20 at 16:24
  • I would have liked more explanation about the proposed solution. It seems like that a non-interactive shell has no BASH_VERSION environment variable, and this is used to detect whether we are in an interactive or non-interactive shell. I have very little experience with such things. but it's weird that there is no dedicated way to test it. – Horror Vacui Sep 11 '20 at 06:47
  • 1
    @HorrorVacui BASH_VERSION doesn't ensure it's in an interactive shell, it only ensures it's in bash. Cause .profile is not used only by Bash. I just copied the content from Ubuntu. To detect an interactive shell, try $PS1. – Simba Sep 11 '20 at 06:56
  • After I added your stuff to my bash profile this break some Winscp commands, like duplicate files – Freedo Sep 29 '20 at 09:37
36

As far as I know, by default tmux runs a login shell. When bash is invoked as an interactive login shell, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile. So you have to put source ~/.bashrc in one of those files.

Another way to solve this issue is to put in your file .tmux.conf the line:

set-option -g default-shell "/bin/bash"
andreatsh
  • 2,025
  • 1
    I added the source ~/.bashrc line to my .bash_profile, tried logging out and back in, create a new tmux session, but no change. Any ideas? – J.W.F. Nov 08 '16 at 02:52
  • 1
    Try to put in your file .tmux.conf the line set-option -g default-shell "/bin/bash". This should solve your issue (at least I hope so)! – andreatsh Nov 08 '16 at 22:06
  • After reloading my tmux configuration, this solved my issue! Want to modify your answer or create a new one? I would be happy to mark it as accepted. :) – J.W.F. Nov 17 '16 at 04:24
  • You're kind, I quickly modified my answer! – andreatsh Nov 17 '16 at 15:08
  • 3
    Note for macOS users: if you've installed bash via Homebrew and this doesn't work, change "/bin/bash" to "/usr/local/bin/bash". –  Apr 05 '18 at 14:48
  • This didn't work for me. I have the same issue (bashrc not getting sourced on new tmux windows/sessions). /bin/bash is set as default-shell as displayed when running tmux show-options -g. Any ideas? :) – joker Apr 21 '19 at 15:04
13

Adding the following to .tmux.conf:

set-option -g default-shell "/bin/bash"

DOES NOT yield the desired result.

Only when adding source "$HOME/.bashrc" to ~/.bash_profile the intended result is achieved.

This will work on an active tmux session when opening a new window or pane, and also when detaching and opening a new tmux session.

Tested on:

VERSION="16.04.2 LTS (Xenial Xerus)"
tmux 2.1
  • 1
    I wonder what are the downsides of the proposed solution. There is a reason why bash uses different files and sourcing bash_rc unconditionally goes against that reason. – Horror Vacui Sep 11 '20 at 06:51
4

The solutions sourcing ~/.bashrc via ~/.profile (or ~/.bash_profile), including the top answer, work great.

An alternative that also works for me with Ubuntu 20.04/tmux 3.0a is adding this to ~/.tmux.conf:

set-option -g default-command bash

This alternative also solves another annoying tmux issue: doubling up on prepends to $PATH found in ~/.bashrc and ~/.profile. (post I got the idea from)

3

Modify your $HOME/.tmux.conf file with the following:

set-option -g default-shell "/usr/bin/bash"
set-option -g default-command bash

That should cover it. While you are at it, why not put the dotfile in the $HOME/.config/tmux folder where it belongs without the dot. And, add color output and a reload key binding to $HOME/.config/tmux/tmux.conf:

set -g default-terminal "screen256color"

bind r source-file "${HOME}/.config/tmux/tmux.conf"

If tmux -V < 3.1, add an alias to $HOME/.bashrc to load the config file from this location:

alias tmux="tmux -f ${HOME}/.config/tmux/tmux.conf"

Or make it a system-wide config at /etc/tmux.conf, the default location.

2

Andres Salgado's answer worked for me. Just to add to it.

I had this issue when working on Ubuntu 20.04.

Here's how I fixed it:

Firstly, create a file called .tmux in the home directory of your machine, which is ~/.tmux.conf.

Next, put in the configuration that you want to use for Tmux inside it and save it. For me the configuration I needed was the same as the GNU screen package that comes default with Ubuntu uses, so I copied the content of the ~/.bashrc file into the ~/.tmux.conf file. This way if I have to edit any of the configurations for Tmux, I wouldn't tamper with the one for the GNU screen.

Note: You could skip this step and just use the ~/.bashrc file if you do not care for separation of concerns.

Next, add the file to either the ~/.bash_profile, ~/.bash_login, and ~/.profile file. It should be added at the bottom of the file:

source "$HOME/.tmux.conf"

OR

source "$HOME/.bashrc"

Here's an example:

# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

the default umask is set in /etc/profile; for setting the umask

for ssh logins, install and configure the libpam-umask package.

#umask 022

if running bash

if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi

set PATH so it includes user's private bin if it exists

if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi

set PATH so it includes user's private bin if it exists

if [ -d "$HOME/.local/bin" ] ; then PATH="$HOME/.local/bin:$PATH" fi

source "$HOME/.tmux.conf"

Note: The ~/.bash_profile file takes the first precedence, then the ~/.bash_login file as the second precedence, and then the ~/.profile file as the last precedence.

That's all.

I hope this helps

  • According to your example, if you add source "$HOME/.bashrc" to the end of ~/.profile, a login shell will source ~/.bashrc twice. – Derek Mahar Jun 27 '21 at 21:08