Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I'm new to Ubuntu. I'm running 13.10 Desktop.

I wanted to set some system wide aliases and a custom prompt for bash. I found this article:

https://help.ubuntu.com/community/EnvironmentVariables

Following the advice in this article, I created /etc/profiles.d/profile_local.sh. It is owned by root and has permissions of 644 just like the other scripts there:

root@ubuntu:/etc/profile.d# ll
total 28
drwxr-xr-x   2 root root  4096 Mar 23 08:56 .
drwxr-xr-x 135 root root 12288 Mar 23 09:15 ..
-rw-r--r--   1 root root   660 Oct 23  2012 bash_completion.sh
-rw-r--r--   1 root root  3317 Mar 23 07:36 profile_local.sh
-rw-r--r--   1 root root  1947 Nov 23 00:57 vte.sh

I have further confirmed that /etc/profile calls /etc/profile.d. It contains this code block:

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

Upon login, it does not appear that the custom script, profile_local.sh I created gets sourced. However if after login I 'source /etc.profile.d/profile_local.sh', I get the expected behavior, my custom aliases, and custom prompt.

What am I doing wrong?

Contents of script 'profile_local.sh':

# 3/23/14 - Copied from Gentoo /etc/bash/bashrc
# Placed in /etc/profile.d as described at:
# https://help.ubuntu.com/community/EnvironmentVariables

# This file is sourced by all *interactive* bash shells on startup,
# including some apparently interactive shells such as scp and rcp
# that can't tolerate any output.  So make sure this doesn't display
# anything or bad things will happen !


# Test for an interactive shell.  There is no need to set anything
# past this point for scp and rcp, and it's important to refrain from
# outputting anything in those cases.
if [[ $- != *i* ]] ; then
        # Shell is non-interactive.  Be done now!
        return
fi

# Bash won't get SIGWINCH if another process is in the foreground.
# Enable checkwinsize so that bash will check the terminal size when
# it regains control.  #65623
# http://cnswww.cns.cwru.edu/~chet/bash/FAQ (E11)
shopt -s checkwinsize

# Enable history appending instead of overwriting.  #139609
shopt -s histappend

# Change the window title of X terminals 
case ${TERM} in
        xterm*|rxvt*|Eterm|aterm|kterm|gnome*|interix)
                PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
                ;;
        screen)
                PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\033\\"'
                ;;
esac

use_color=false

# Set colorful PS1 only on colorful terminals.
# dircolors --print-database uses its own built-in database
# instead of using /etc/DIR_COLORS.  Try to use the external file
# first to take advantage of user additions.  Use internal bash
# globbing instead of external grep binary.
safe_term=${TERM//[^[:alnum:]]/?}   # sanitize TERM
match_lhs=""
[[ -f ~/.dir_colors   ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
[[ -z ${match_lhs}    ]] \
        && type -P dircolors >/dev/null \
        && match_lhs=$(dircolors --print-database)
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true

if ${use_color} ; then
        # Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
        if type -P dircolors >/dev/null ; then
                if [[ -f ~/.dir_colors ]] ; then
                        eval $(dircolors -b ~/.dir_colors)
                elif [[ -f /etc/DIR_COLORS ]] ; then
                        eval $(dircolors -b /etc/DIR_COLORS)
                fi
        fi

        if [[ ${EUID} == 0 ]] ; then
                PS1='\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
        else
                PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
        fi

        alias ls='ls --color=auto'
        alias grep='grep --colour=auto'
else
        if [[ ${EUID} == 0 ]] ; then
                # show root@ when we don't have colors
                PS1='\u@\h \W \$ '
        else
                PS1='\u@\h \w \$ '
        fi
fi

# Try to keep environment pollution down, EPA loves us.
unset use_color safe_term match_lhs

TZ="PST8PDT"

alias ll='ls -la'
alias dig='dig +search'
alias dir='ls -ba'

alias edit="ee"
alias ss="ps -aux"
alias dot='ls .[a-zA-Z0-9_]*'
alias news="xterm -g 80x45 -e trn -e -S1 -N &"

alias more="less"
alias c="clear"
alias m="more"
alias j="jobs"

# common misspellings
alias mroe=more
alias pdw=pwd
share|improve this question
1  
You can add it in to your original post. –  Mr.Lee Mar 23 at 17:10
1  
Have you tried <pre></pre> –  Mr.Lee Mar 23 at 17:22
1  
@Mr.Lee : it isn't necessary for bash files. –  MrVaykadji Mar 23 at 17:34
1  
No, it's not executable but neither are the other two scripts. However I changed it and tried again. Still no luck. –  Drew Mar 23 at 17:38
1  
This has nothing to do with adding .sh, it is irrelevant and anyway the files in profile.d are sourced, not executed which is slightly different and does not require the file to be executable. The issue here is that profile &co are not read by non-login scripts. –  terdon Mar 23 at 17:41

1 Answer 1

up vote 25 down vote accepted

To understand what's going on here, you need to understand a little background information about how shells (bash in this case) are run.

  • When you open a terminal emulator (gnome-terminal for example), you are executing what is known as an interactive, non-login shell.

  • When you log into your machine from the command line, or run a command such as su username, you are running an interactive login shell.

  • When you log in graphically, you are running something completely different, the details will depend on your system and graphical environment but in general it is the graphical shell that deals with your login. While many graphical shells (including the Ubuntu default) will read /etc/profile not all of them do.

  • Finally, when you run a shell script, it is run in a non-interactive, non-login shell.

Now, the files that bash will read when launched depend on the type of shell it is running as. The following is an excerpt of the INVOCATION section of man bash (emphasis mine):

When bash is invoked as an interactive login shell, or as a non-inter‐ active shell with the --login option, it first reads and executes com‐ mands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.

What all this means is that you are editing the wrong file. You can test this by dropping to a virtual console using Ctrl+Alt+F2 (return to the GUI with Alt+F7, or F8 depending on your setup) and logging in there. You will see that your prompt and aliases are available.

So, in order to have the setting you want applied to non-login shells, the type you get each time you open a terminal, you should make your changes to ~/.bashrc instead. Alternatively, you can also place your aliases in the file ~/.bash_aliases.

For more details on which file should be used for what, see here.


NOTES:

  • Debian (and by extension Ubuntu) also has the default ~/.profile source ~/.bashrc. This means that any changes you make to ~/.bashrc will also be inherited by login shells but i) this is not the case in all Linux/Unix machines and ii) the inverse is not true which is why you should generally always work with ~/.bashrc &co rather than ~/.profile or /etc/profile.

  • Also, a general note on usage, changes made to the configuration files in /etc will affect all users. This is usually not what you want to do and should be avoided. You should always use the equivalent files in your home directory (~/).

  • The various configuration files are read sequentially. Specifically, for login shells, the order is:

    /etc/profile -> /etc/profile.d/* (in alphabetical order) -> ~/.profile
    

    This means that any setting in ~/.profile will overwrite anything set in the previous files.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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