Lei Mao bio photo

Lei Mao

Machine Learning, Artificial Intelligence, Computer Science.

Twitter Facebook LinkedIn GitHub   G. Scholar E-Mail RSS


Sometimes, when I remotely login to some Linux computers or use Docker containers, I would find the shell is plain black and white, which is different from the colorful shell I used to deal with on my local machine. This is sometimes causing me trouble to look for libraries, executables, and folders. Sometimes, some executables could be called directly from a local shell but from a remotely login shell they are not directly callable.

It turns out that the shell is an executable and it is “configured” by special shell scripts such as ~/.bashrc, ~/.profile, ~/.bash_profile. In this blog post, I would like to briefly discuss the differences between these scripts.


I modify ~/.bashrc file from time to time, because sometimes I would like to set some environment variables, including PATH which is an environmental variable in Linux and other Unix-like operating systems that tells the shell which directories to search for executable files. But I have been ignoring its commented block at the beginning for decades.

$ cat ~/.bashrc 
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

This means that in a local shell, and if we use bash, this shell script will be executed immediately after bash is executed. There are many other shell executable variants, such as zsh. ~/.bashrc is only specific to bash.

There are many code in the ~/.bashrc that makes the shell looks colorful. For example,

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'


The comment block from ~/.profile explictly tells us that it will be executed for the login shells. However, if ~/.bash_profile or ~/.bash_login exists, ~/.profile will not be executed.

$ cat ~/.profile 
# ~/.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"

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then

The default content of ~/.profile is simple. Most likely, it inherits whatever there are in the ~/.bashrc, and adds some user specific executable filepath to the environment variable PATH. So if there are commands that make the shell looks colorful in the ~/.bashrc, the login shell should also look colorful.


Unfortunately, in most of my login trials, the shells were never coloful, and sometimes the environment variables do not match my expectation. This is because there exists a ~/.bash_profile therefore ~/.profile or ~/.bashrc is never executed. Usually the ~/.bash_profile will be empty, this means that we would not have the environment and appearance as we have in our local shell.

To make the login shell “back to normal”, we could either delete the ~/.bash_profile or modify the ~/.bash_profile by adding some commands like

. "$HOME/.profile"


Sometimes, a non-color shell could be helpful. It tells you that are not working in local shell. It could either be a Docker shell or a remote login shell. Knowing what shell we are dealing with, we would be less likely to do dangerous operations. For example, in a Docker shell, we could do almost anything, such as rm -rf / without sudo, without harming the local system.