This question is about best practices. I know logging in over secure shell or switching users su, and su -l have different effects. Also, in the event you make a typo in the configuration, you still want to be able to log in. Where is/are the/some ideal place/s to store color definitions? At the moment I have them in .bash_profile. Is it ok to store them in .bashrc?

Configuration Locations:

According to the ArchWiki

  • /etc/profile Sources application settings in /etc/profile.d/*.sh and /etc/bash.bashrc.
  • ~/.bash_profile Per-user, after /etc/profile.
  • ~/.bash_login (if .bash_profile not found)
  • ~/.profile (if .bash_profile not found)
  • /etc/skel/.bash_profile also sources ~/.bashrc.
  • ~/.bash_logout
  • /etc/bash.bashrc Depends on the -DSYS_BASHRC="/etc/bash.bashrc" compilation flag. Sources /usr/share/bash-completion/bash_completion
  • ~/.bashrc Per-user, after /etc/bash.bashrc.

Let's save I have two color definitions, one for the command prompt and one for the ls command.

set_prompt () {
    Last_Command=$? # Must come first!

    PS1="${Graydark}\t "
    if [[ $Last_Command == 0 ]]; then
        PS1+="$Greenlight$Checkmark "
        PS1+="$Redbold$FancyX "
    if [[ $EUID == 0 ]]; then
        PS1+="\\u@$Redbold\\h "
        PS1+="$Greenlight\\u$White@$Redbold\\h "
    PS1+="$Graydark\\W $Redbold\\\$$Reset "

set_ls () {
    # Highlight
    export LS_COLORS

closed as primarily opinion-based by Thomas Dickey, Anthon, Wouter Verhelst, garethTheRed, Gert May 25 '16 at 13:48

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.


I would put environment variables in .bash_login or .bash_profile, since they are (when exported) inherited to subshells and don't need to be reset for every shell invocation. Not that resetting them would cost practically anything, but in case I want to set an envvar to something else for the duration of a subshell. That's hard to do if the .bashrc overrides the setting.

For everything else (including functions), you want to put them in .bashrc, since .bash_login and friends won't be read by subshells. .bashrc usually will be, through one of the profile/login scripts.

Of course your use of PS1 is a bit different, since you want a function that changes it.

(Bash is a bit funny with the initializations files. Login shells read bash_profile and friends, but not bashrc. Non-login shells work exactly the opposite. So there's no file that will be read by all shell invocations, unless bashrc is sourced by the profile scripts. ref. https://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files )

Choosing between .profile, .bash_profile and .bash_login is completely up to you, and choosing between global configuration and per-user configuration of course depends on if you want to change the behaviour for all users, or only one.

As for typos, keep a shell open and test run the scripts after changing them. :) Not that a simple typo would matter, at worst it will stop reading the init script and/or mess up the rest of the settings. Unless you have an "exit" in your .bashrc for some reason.


I put PS1 code in bashrc all the time.

My code is as follows:

export PS1="\[\e[01;37m\][\[\e[0m\]\[\e[01;32m\]\u\[\e[0m\]\[\e[00;37m\]@\[\e[0m\]\[\e[01;34m\]\h\[\e[0m\]\[\e[00;37m\] \[\e[0m\]\[\e[00;37m\]\t\[\e[0m\]\[\e[01;37m\] \W \e[1;37m(\e[1;32m|\e[1;33m|\e[1;31m|\e[1;37m]\\$ \[\e[0m\]"

I use a different PS1 for root (/root/.bashrc) - red username, and for production vs local servers - different format.

See this reddit for cool codes. The newline trick is really useful!


Since the question is essentially asking for opinions, you will get different answers. A good design practice, for example, uses as few places as possible to provide a given feature. Some put information like this in the system area to reduce the amount of work done by users to customize their shell environment.

In my environment, I use the terminal database and eliminate where possible the sort of hardcoded lists of escape sequences suggested in this question. For example, in my directory editor, I use names rather than numbers (and don't use LS_COLORS at all):

enter image description here

The BSDs likewise use the terminal database in their ls implementation, but with less configurability for the "color ls" feature. Although it is more configurable, however, GNU ls gives results which are questionable. For example

TERM=vt100 dircolors


setenv LS_COLORS 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:'

which (see the ncurses FAQ How do I get color with VT100?) is not an improvement.

Others use tput for obtaining the actual colors, allowing one to change the customization through a single environment variable (TERM), rather than distributing the information across several configuration files.

If you put the customization in the system area, there is the drawback of maintaining your customization as updates are applied to the system. Plus some (as in Fedora) have already been there (see Features/256 Color Terminals) and coordinating your changes for one or more machines can be involved.

  • Looking for arguments, not opinions. You may have an opinion, but I'd like to know why. – Jonathan Komar May 25 '16 at 8:40

I would like to suggest you to put all your aliases and functions in a file, tipically ~/.bash_aliases.

If not yet present, you can add in your .bashrc (or wherever you need) those lines:

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases

Taken from an Ubuntu .bashrc, of course you can leave out the comments...
Under Ubuntu, for example, that is a standard, but the use of such kind of files is older then Ubuntu...

It will be cosier to set up an account on a new machine.

Not the answer you're looking for? Browse other questions tagged or ask your own question.