Per default, gnome-terminal does not start bash as a login shell (I assume you mean bash started inside a gnome-terminal). That means bash will not read /etc/profile
or ~/.profile
. As you have correctly observed, bash will read those files if started as a login shell.
The quick fix to your problem is to configure gnome-terminal to start bash as a login shell so it will read /etc/profile
. To do that you have to enable "Run Command as a login shell" in the gnome-terminal "Profile Preferences" reachable from the Edit menu.
I do not recommend doing this because it messes up the distinction between ~/.profile
and ~/.bashrc
. Ideally ~/.profile
should do stuff which is required only once, during login, while ~/.bashrc
should do stuff which is required everytime bash is started.
There is a question and answer at superuser talking about the difference between bashrc and profile. Read there for more information.
From your problem description it seems that the rvm script needs to be loaded only once, during login. As far as I know Ubuntu has configured the graphical login to read /etc/profile/
and ~/.profile
. That means, after logging out and a logging in once, the rvm script should be active. If it still doesn't work, then perhaps the rvm script needs to be loaded for every bash session. If that is the case then bashrc
is the more appropriate place for the script.
You cannot have a function that outputs both text and color, in the bash prompt. Everything the function outputs gets taken literally. I suggest going about it a different way.
First off, what the prompt tries to do, is check if you're in a git tree, and if so, add a colored (branch) to the prompt. Instead of checking everytime the prompt is printed, you really only need to do that check whenever you change directory, so we can override the only three commands that can change directory to set the variable git_branch to the name of the current branch, if any.
cd() {
builtin cd "$@" || return
git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
pushd() {
builtin pushd "$@" || return
git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
popd() {
builtin popd "$@" || return
git_branch=$(git branch 2>/dev/null|sed -n '/^[*] /s///p') || true
}
Next up, check if stderr is a terminal, and set colors with tput
user_color= dir_color= git_color= reset=
if [[ -t 2 ]]; then
user_color=$(tput setaf 2; tput bold)
dir_color=$(tput setaf 4; tput bold)
reset=$(tput sgr0)
fi
And a function that outputs one of two colors based on whether there are changes or not
_git_color() {
[[ $git_branch && -t 2 ]] || return
if git diff --quiet >/dev/null 2>&1; then
tput setaf 1
else
tput setaf 3
fi
}
Now, putting the prompt together. This is a bit cumbersome as some variables should be expanded at assignment (now), while some should be expanded when the prompt is printed, so we need to alternate quotes, plus it gets rather long. Using an array for this should help keep the overview
prompt=(
"\[$user_color\]" '\u@\h' "\[$reset\]"
: "\[$dir_color\]" '\w' "\[$reset\]"
'${git_branch:+ (}'
'\[$(_git_color)\]' '$git_branch' "\[$reset\]"
'${git_branch:+)}'
'\$ '
)
I ommited the debian_chroot stuff here, I've never needed it myself, you can of course add that if you want. Finally, join the prompt array and clean up the variables we no longer need.
printf -v PS1 %s "${prompt[@]}"
unset user_color dir_color reset prompt
Best Answer
I've found that bash versions >= 4.2.29 have a new
direxpand
shopt setting. (Seeman docs/bash.1
if you check out a new bash, or see bash.1 from line 8951)If one uses Quantal Quetzal 12.10 or otherwise gets hold of (or checks out and builds) a new bash, then:
Gives me the behavior I want, need and love.
Workaround: In the meantime, Ctrl+Alt+E instead of Tab does what I want too. But is awkward.
BTW, There are several threads called "bash tab variable expansion question?" in gnu.bash.bug. From reading them, I found the info here.