I just spent a lot of time reading up on login and interactive shells and why one should or should not set environment variables, shell functions, etc. in the various profile and bashrc files. In this post it was mentioned that bash specific things like prompt options should be set in ~/.bashrc. That led me to wonder about the PS1 variable. In all the examples I've seen regarding this they have something like export PS1=""
. Should this really be exported to the environment since it only has meaning for bash? Just having PS1=""
in my ~/.bashrc produces the intended effect for me, but I'm wondering if I'm missing something.

- 273
1 Answers
That's correct: PS1
is only meaningful in interactive instances of bash, so it should be set in ~/.bashrc
and should not be exported. PS1
is also meaningful in other shells, but it has a different meaning, because prompt expansions differ between shells. In fact, even between instances of bash, PS1
can have different meanings, since the meaning depends on shell options (at least promptvars
).
Exporting PS1
to the environment from .profile
is a throwback to the 1970s, when there was only one shell that used it (the Bourne shell) and it didn't have a configuration file. It still works today if you always use the same shell and never configure it differently. But all modern shells that aren't designed purely for scripting (csh, ksh, bash, zsh, …) read a configuration file when started interactively (.cshrc
, .kshrc
, .bashrc
, .zshrc
, …), so the 1970s method is no longer necessary. Setting PS1
and other shell-specific settings in a shell-specific file, and not exporting it to the environment, avoids breaking things when you use a different shell configuration or a different shell or a different terminal that isn't capable of showing your usual prompt fanciness. Setting PS1
in a shell-specific file works all the time, whereas setting it in .profile
and exporting it only works in “simple” cases, so there's no reason not to do it the right way, but there are plenty of bad tutorials around the web and even bad default configurations in distributions. C'est la vie.

- 829,060
PS1
from.profile
work for non-login bash shells since they wouldn't source it? Are you saying this would work because the non-login shell would be forked from a login shell so would inheritPS1
through the environment? – Mike Sweeney Dec 06 '15 at 02:33if [ -n "$PS1" ] ; then proceed assuming an INTERACTIVE shell ; fi
-- which commonly appears in people's .bashrc files to only load things like command-completion if this is a user's interactive terminal shell. So, seeing it work there, the same logic winds up in shell scripts, hence the "need" to export it. INSTEAD we should check for interactive / terminal users withtty -s
ortest -t 0
. – DouglasDD Jul 12 '17 at 01:50PS1
test has been in Debian's/etc/profile
for ages, for example. I don't know where this bad practice arose. I suspect it came from one particular use case (maybe detecting rlogin or ssh logins?) where it happened to work. Unfortunately it fails in many other cases, hence the many questions on this topic here and elsewhere. – Gilles 'SO- stop being evil' Jul 13 '17 at 16:04CLICOLOR
andLS_COLORS
either? @DouglasDD does that mean theif [[-z $p1]];then return fi
check in my.bashrc
is flawed? – Startec Sep 01 '17 at 21:25CLICOLOR
andLS_COLORS
are used byls
, so they need to be exported to have any effect.if [[-z $p1]]
is a syntax error. If you meantif [[ -z $PS1 ]]
, that's pretty pointless. To test whether a shell is interactive, check$-
. – Gilles 'SO- stop being evil' Sep 01 '17 at 21:32-z "$PS1"
(or-n
) as the test for interactive shell is OK in .bashrc, .profile, and anything else that is sourced in the shell. It is only flawed/wrong in shell scripts that are executed. – DouglasDD Oct 16 '17 at 20:08PS1
is exported to the environment, for example. Sourcing a script doesn't change anything. – Gilles 'SO- stop being evil' Oct 16 '17 at 20:59PS1
to determine if the shell is interactive should work, since Bash actively unsets it on non-interactive shells, even if it's in the environment. e.g.PS1=foo bash -c 'echo $PS1'
prints an empty line. It's mentioned in the reference manual, though the man page doesn't explicitly say it (only that "PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state"). It looks to have been in the reference manual since Bash 3.2 at least. – ilkkachu Sep 06 '23 at 08:18