PS1 not setting color - linux

I have a PS1 varible in bash_profile file as
orange=$(tput setaf 166);
yellow=$(tput setaf 228);
green=$(tput setaf 71);
white=$(tput setaf 15);
bold=$(tput bold);
reset=$(tput sgr0);
PS1="\[${bold}\]";
PS1+="\[${orange}\]\u"; # username
PS1+="\[${white}\]#";
PS1+="\[${yellow}\]\h "; # host
PS1+="\[${green}\]\w"; # working directory
PS1+="\[${white}\]\$ \[${reset}\]"; # '$' (and reset color)
export PS1;
When I open the new terminal instance it's showing everything properly except color.
But, when I execute the command
source .bash_profile
the color is working. It disappears if I open a new tab.
But, In a new terminal instance, without executing the source command,
the color works for
export PS1="\[\033[35m\]\t\[\033[m\]-\[\033[36m\]\u\[\033[m\]#\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]\$ "
[
What's the reason for this weird behavior?
In breif, in a new terminal session,
first PS1 is not displaying colors but the second ps1 put in the same bash_profile file is displying it.
But the first one is displaying colors when it is sourced.
Note: I am using mac.
I m also sure that the variable is getting set in bash_profile
but the color is not being set.

You should investigate a little more (yes even more).
In each case you should use printf "%q\n" "$PS1" to see the exact value of the variable PS1 (with escaped unprintable characters). Are you just trying to add the colors to an already set PS1 variable? So, if you get the uncolored output, could that be because your code just wasn't executed so the original value is still set? Then just the PROFILE script isn't executed.
.bash_profile typically only is executed when a login-shell is started. Nowadays many distributions don't get it right and are full of workarounds in this matter, so they often contain .bashrc files which source .bash_profile in their beginning. .bashrc is sourced for each new shell, so effectively, your .bash_profile might well be sourced for each shell as well.
I could guess that your .bashrc first sources .bash_profile and then sets the PS1 to a value like yours, just without the colors. But of course, that's guesswork.

I suspect in the OP's case that using ~/.bashrc rather than ~/.bash_profile to set the colours, is all that is required.
Here is how things work:
There are a number of files involved in setting up your bash environment.
/etc/profile sets the system-wide profile
~/.bash_profile, ~/.bash_login, ~/.profile - These are read by default when bash is invoked as a login shell
~/.bashrc - This is always read unless bash is invoked as sh or bash is invoked as bash --norc
~/.bash_logout - login shell cleanup
~/.inputrc - readline initialisation file.
Which files, and order that these files are read depends on exactly how bash is invoked.
There are a number of cases not all of which are mutually exclusive:
login shell
interactive shell
non-interactive shell
posix mode
bash invoked with stdin connected to network connection (yes
it will know)
bash invoked as sh
bash is invoked with the effective uid/gid not equal to the real uid/gid
You need to be aware of which cases apply to your invocation in order to determine which files will be read.
man bash and search for invocation, for the exact details.

I had installed solarized color scheme/theme for my xterm-256 terminal. It was the one causing the issue. When I change the color scheme, the PS1 is working perfectly.

Related

My alias name is referring to old alias not a new one [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between .bashrc, .bash_profile, and .environment?
It seems that if I use
alias ls='ls -F'
inside of .bashrc on Mac OS X, then the newly created shell will not have that alias. I need to type bash again and that alias will be in effect.
And if I log into Linux on the hosting company, the .bashrc file has a comment line that says:
For non-login shell
and the .bash_profile file has a comment that says
for login shell
So where should aliases be written in? How come we separate the login shell and non-login shell?
Some webpage say use .bash_aliases, but it doesn't work on Mac OS X, it seems.
The reason you separate the login and non-login shell is because the .bashrc file is reloaded every time you start a new copy of Bash. The .profile file is loaded only when you either log in or use the appropriate flag to tell Bash to act as a login shell.
Personally,
I put my PATH setup into a .profile file (because I sometimes use other shells);
I put my Bash aliases and functions into my .bashrc file;
I put this
#!/bin/bash
#
# CRM .bash_profile Time-stamp: "2008-12-07 19:42"
#
# echo "Loading ${HOME}/.bash_profile"
source ~/.profile # get my PATH setup
source ~/.bashrc # get my Bash aliases
in my .bash_profile file.
Oh, and the reason you need to type bash again to get the new alias is that Bash loads your .bashrc file when it starts but it doesn't reload it unless you tell it to. You can reload the .bashrc file (and not need a second shell) by typing
source ~/.bashrc
which loads the .bashrc file as if you had typed the commands directly to Bash.
Check out http://mywiki.wooledge.org/DotFiles for an excellent resource on the topic aside from man bash.
Summary:
You only log in once, and that's when ~/.bash_profile or ~/.profile is read and executed. Since everything you run from your login shell inherits the login shell's environment, you should put all your environment variables in there. Like LESS, PATH, MANPATH, LC_*, ... For an example, see: My .profile
Once you log in, you can run several more shells. Imagine logging in, running X, and in X starting a few terminals with bash shells. That means your login shell started X, which inherited your login shell's environment variables, which started your terminals, which started your non-login bash shells. Your environment variables were passed along in the whole chain, so your non-login shells don't need to load them anymore. Non-login shells only execute ~/.bashrc, not /.profile or ~/.bash_profile, for this exact reason, so in there define everything that only applies to bash. That's functions, aliases, bash-only variables like HISTSIZE (this is not an environment variable, don't export it!), shell options with set and shopt, etc. For an example, see: My .bashrc
Now, as part of UNIX peculiarity, a login-shell does NOT execute ~/.bashrc but only ~/.profile or ~/.bash_profile, so you should source that one manually from the latter. You'll see me do that in my ~/.profile too: source ~/.bashrc.
From the bash manpage:
When bash is invoked as an
interactive login shell, or as a
non-interactive shell with the
--login option, it first reads and executes commands 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 a login shell exits, bash
reads and executes commands from the
file ~/.bash_logout, if it exists.
When an interactive shell that is not a login shell is started, bash
reads and executes commands from ~/.bashrc, if that file exists. 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
~/.bashrc.
Thus, if you want to get the same behavior for both login shells and interactive non-login shells, you should put all of your commands in either .bashrc or .bash_profile, and then have the other file source the first one.
.bash_profile is loaded for a "login shell". I am not sure what that would be on OS X, but on Linux that is either X11 or a virtual terminal.
.bashrc is loaded every time you run Bash. That is where you should put stuff you want loaded whenever you open a new Terminal.app window.
I personally put everything in .bashrc so that I don't have to restart the application for changes to take effect.

turning on / off environment variables

I have been trying to set the $PATH environment variable to point to different paths as I need them, but I have run into some issues.
The main thing is that when I set the PATH to point to my service that I need, I want it to stay that way in all subsequent bash shells. That is, when I open another bash shell it will be set there as well, until I decide to switch it back. And when I switch the PATH back to its original value. I want it to stay that way.
I added a small script to my .bashrc, I also tried doing a separate script that will change environment variables. But the problem stays: If I open a new bash shell, it inherits the default environment variables and the default PATH.
I am setting those to enable the use of a daemon service. I tried turning on/off the service itself. That does not work because the paths have to be changed or else the shell would try to use those environment paths, but the service being off it will just hang.
I tried running a small C program wrapper to do those things but I ran into the same issue.
In order for environment variable to exist across shell sessions you will need to place those variables into a shell configuration file. This is usually done in either ~/.bashrc or ~/.profile (if you are using Bash). For example, in my ~/.profile file I have:
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
I can add to that path as much as I want. The $PATH variable at the end will append whatever is current in the path.
If you need scripts to be able to access the variables, you should put the PATH into the .bashrc file. (what is the difference between .bashrc and .profile)
If you make a change to one of your shell configuration files, the changes will not be in effect until those files are used again. Those files are only used when the shell is first initialized. In order to make changes take effect, you need to log out and back in, or open a new shell and close the old, or source the file that you made changes to.
$ vim ~/.bashrc (edit the file)
$ source ~/.bashrc (then reinitialize the shell with the file)
If you only need a variable to be available in the current shell and any subprocesses, using export would be all you need.
You might also be interested in this snippet. It reloads the .bashrc in any shell, whenever it is modified. (After re-editing the .bashrc file, press (or run a command) to cause the new .bashrc to be reloaded.)
# Make sure our version of the .bashrc file is up-to-date, or reload it.
chk_bashrc_timestamp () {
if [[ "$_BASHRC_TIMESTAMP" -lt "$(get_file_timestamp "$HOME/.bashrc")" ]]; then
echo >&2 "Reloading .bashrc..."
. ~/.bashrc
fi
}
_BASHRC_TIMESTAMP=$(date +%s)
PROMPT_COMMAND=chk_bashrc_timestamp
The only difficulty is, you must not use $PATH in the definition of PATH, or it will repeat the whole PATH each time it is needed:
Use
SYSPATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
PATH="$HOME/bin:$SYSPATH:/opt/mystuff"
instead of
PATH="$HOME/bin:$PATH:/opt/mystuff"
I have used this with much satisfaction in my own .bashrc, except that I have protected my PATH from reloading each time by setting it in an if statement. (You may find you have other things you need to protect this way.)
if _BASHRC_WAS_RUN 2>/dev/null; then
:;
else # Stuff that only needs to run the first time we source .bashrc.
# Useful to allow resourcing new changes
export PATH="$HOME/bin:$HOME/.cabal/bin: ..."
alias _BASHRC_WAS_RUN=true
fi

When I execute bash, the $PATH keeps repeating itself

I have added entries such as the following in my /etc/bashrc (on Fedora).
#=========== Maven Related variables
export JAVA_HOME='/usr/java/default'
export PATH=${JAVA_HOME}:$PATH
#=========== Maven Related variables
export M2_HOME=/usr/local/apache-maven/apache-maven-3.0.4
export PATH=${M2_HOME}/bin:$PATH
#=========== Ant Related variables
export ANT_HOME=/usr/local/apache-ant
export Path=${ANT_HOME}/bin:$PATH
Now, each time that I execute bash command to refresh the environment variables, all these additions are repeated, and the PATH just keep adding itself recursively; if I keep doing bash for a few dozen times, then the $PATH becomes a hundred lines of repeating content. What am I doing wrong?
Note that I have added these entries to /etc/bashrc since I want to have these values in PATH no matter what user I login as.
Thanks,
Shannon
Don't set your PATH incrementally in .bashrc; set it once in .profile and leave it alone thereafter. Or, since you mention /etc/bashrc, don't set the PATH incrementally in /etc/bashrc; set it once in /etc/profile and leave it alone.
One side-benefit; things will work a little faster.
See also the code in How do I manipulate PATH elements in shell scripts for code to clean up a repetitive PATH.
If by this statement:
... execute bash command to refresh the environment variables ...
you mean that you are entering the command
bash
at the command prompt, you are not "refreshing the environment variables". You are launching a new subshell of the current shell. The new shell inherits the path of the original shell, to which you are once again making additions. Each time you do this the PATH will get longer.
You can use something like:
PATH=$(echo "$PATH" | awk -v RS=: -v ORS=: '!(a[$0]++)' | sed 's/:$//')
to clean up your path after changing it. Also, since the the first match is used when scanning the path, having duplicates doesn't really matter.
I had also faced the same problem (CentOS). This is how I fixed it.
Added the following lines to my user's .profile
export PATH=/usr/local/apache-maven-3.3.3/bin:$PATH
export JAVA_HOME=/usr
export SHELL=/bin/bash
# to run bash (because ksh was my default shell)
/bin/bash
No changes to my user's .bashrc file
No changes to /etc/profile
No changes to /etc/bashrc

standardizing prompts across shells in cygwin

I'm having a heck of a time standardizing my prompts across the different shells I have installed for cygwin.
Installed shells:
bash (default login shell)
sh
csh (tcsh, actually)
ksh
zsh
My prompt is standardized across bash, csh, and zsh, but I can't get sh and ksh on board.
The prompt I'm looking to use across all shells is similar to the following:
20121216 15:18:04 [shell] # date and time in yellow, shell in red
user#hostname pwd # user#host in green, pwd in yellow
$ # white
I've got it set the way I want it for bash with the following line in /etc/profile:
PS1="\[\e]0;\w\a\]\n\[\e[33m\]\D{%Y%m%d %H:%M:%S} \[\e[31m\][bash]\n\[\e[32m\]\u#\h \[\e[33m\]\w\[\e[0m\]\n\$ "
And I've got it set for csh with the following line in .tcshrc:
set prompt="\n%{\033[33m%}%Y%W%D %P %{\033[31m%}[csh]\n%{\033[32m%}%n#%M %{\033[33m%}%~\n%{\033[0m%}$ "
And I've got it set for zsh with the following lines in .zshrc:
PROMPT="
%{$fg[yellow]%}%D{%Y%m%d} %* %{$fg[red]%}[zsh]%{$reset_color%}
%{$fg[green]%}%n#%m %{$reset_color%}%{$fg[yellow]%}%~%{$reset_color%}
$ "
But I can't seem to set a default prompt for sh or ksh anywhere. I can open both of them and manually set PS1="$ ", but I cannot for the life of me get it to set automatically. The sh prompt looks identical to the bash prompt, and the ksh prompt is gibberish (bc it doesn't like the syntax of PS1 that it's inheriting from bash, I assume).
Things I've tried unsuccessfully:
setting PS1 in /etc/profile (in a case statement reading the shell
name from echo $0)
setting PS1 in .kshrc
setting PS1 in .shrc
setting PS1 in .sh_profile
setting PS1 in .profile
It seems that cygwin just doesn't execute the files listed above when I launch one of those shells. Note that I only ever launch those shells from within bash.
Any ideas? (Sorry for the book, I'm just trying to be thorough.)
The official Korn shell ksh93 will read /etc/profile and ~/.profile on login, in that order.
If ksh is not acting as a login shell it will try to read the file referred to by $ENV, or $HOME/.kshrc if ENV is not set.
Older versions (sun's ksh88 in particular) suffered from a chicken and egg situation because you could only set ENV in ~/.profile, but then you still had to source the file yourself with . $ENV.
Note that ENV and PS1 have to be exported in order to be picked up by ksh instances spawned after login (say, from screen or tmux).

Missing gem after changing shell to ksh

my MAC is getting hair-wired after I change console to ksh, and change it back again to /bin/bash
the console prompt is now static bash-3.2 regardless current directory I am in. Meanwhile in .bash_profile I have set # modify console
export PS1="\W > "
rake gem and few others in Ruby are missing, although it was reinstalled again after I run bundle install , but there are subsequent strange issue, e.g. rake command does not hit the right rake file..
Any idea?
Thanks a lot.
The .bash_profile is only run by bash when you first log in. (It only gets run by Terminal if you have Terminal set up to make each shell a "login shell"). If you have commands that you want to get run every time you fire up bash, even if it's not a login shell, you should put them in .bashrc instead. But you can always make a shell be a login shell by running bash --login instead of just bash.
Not sure where your ksh comes from, but note that it doesn't understand '\W' etc in the prompt string, so I would expect you to get a literal '\W' in the prompt instead of the expanded working dir. If you're running ksh as a login shell, it's probably something in the .profile (or /etc/profile, etc.). ksh doesn't have an exact equivalent of .bashrc, but if $ENV is set to a filename after the profile runs, that file is executed as well (even on non-login shells, if ENV is already set when the shell starts). Ksh, of course, ignores .bash_profile and .bashrc.
Since there's no ref to gems in the body of your question (anymore?), you might want to change the question and remove the Ruby tag...

Resources