4

I am following Cross-Compiled Linux From Scratch - Embedded.

In section 3.3 "Setting Up the Environment", PS1 is declared in .bash_profile.

When I log in as su - clfs, both .bash_profile and .bashrc get executed. When I log in as su clfs, only .bashrc gets executed.

In both cases, PS1 never updates the terminal.

When I put PS1 in .bashrc, it does update the terminal.

The CLFS book has put it in .bash_profile:

cat > ~/.bash_profile << "EOF"
exec env -i HOME=${HOME} TERM=${TERM} PS1='\u:\w\$ ' /bin/bash
EOF

What is the suitable location for PS1?

Israr
  • 395

3 Answers3

15

The PS1 shell variable should be set in ~/.bashrc for the bash shell as that is the initialisation file that is read for interactive shell sessions.

Note that this variable is a shell variable, not an environment variable (it does not make sense to let child processes inherit its value, and it's only the current shell that uses it). It therefore does not need to be exported with export.

Related:

You shouldn't need to start bash from any of the shell's startup files. Starting a particular shell from ~/.profile (or the corresponding file related to your login shell) may possibly be warranted if the system that you're running on does not allow you to change your login shell. Care should be taken to not start the other shell if that is the shell already executing the file though, or you may end up in an infinite loop of sorts.

The exec code that you add to your ~/.bash_profile should never be needed. I suppose it's a way of getting ~/.bashrc to be parsed (it starts an interactive shell, and interactive bash shells read ~/.bashrc). A better way of doing that would be to have one of the files source the other, for example using this in ~/.bash_profile:

if [[ -f $HOME/.bashrc ]]; then
    source "$HOME/.bashrc"
fi

Then set PS1 in ~/.bashrc (there should be no need to touch HOME or TERM).

The other thing that the command does is to clean out all other environment variables using env -i. Unless you have very specific reasons to do this, you should not do that from your ordinary shell startup files.

Kusalananda
  • 333,661
  • Then why its been there like this : exec env -i HOME=${HOME} TERM=${TERM} PS1='\u:\w\$ ' /bin/bash .A mistake or any other possible purpose. – Israr Oct 28 '19 at 09:01
  • "it does not make sense to let child processes inherit its [PS1] value" -- well, I'm not so sure about that. If you start a shell for some special purpose, with the expectation that it would be closed after doing some task, it would be useful to be able to set a marker in the prompt. But you can't do that if the shell always resets PS1 from .bashrc. Sure, anything like that would need to be shell-specific anyway, but it's not that impossible an idea, IMO. Prepending some fixed string to an existing PS1 would also work for many shells (or you could just make it configurable) – ilkkachu Oct 28 '19 at 10:03
  • Though what with Bash unsetting PS1 when launched non-interactively, doing that gets somewhat hard. – ilkkachu Oct 28 '19 at 10:04
  • @ilkkachu I'm just not a fan of polluting the environment with unnecessary environment variables (as you say, sometimes it may be necessary, but that would be under special circumstances). Some shells completely ignore the value of PS1 in the environment, always. – Kusalananda Oct 28 '19 at 10:25
  • 1
    Paragraph two is gold: "...shell variable, not an environment variable..." I never realised that. Now the rest makes sense. I will move my PS1 and add a comment linking to this answer. – Leo Oct 28 '19 at 21:03
  • @LightnessRaceswithMonica : Yes, thats the prime requirement of CLFS.Start from Linux Headers to fully Built and Bootable Kernel is the Journey.Definitely Clean Environment is the Requirement. So It is there for a purpose . The other thing that the command does is to clean out all other environment variables using env. . Hence proved, i think so, right? – Israr Oct 28 '19 at 21:14
  • Still one doubt remains, is why it is there in .bash_profile , when it is not showing me up in Terminal in any mode whether it is login/nologin or interactive? – Israr Oct 28 '19 at 21:22
  • 1
    @IsrarSayed This is what I don't understand. You can bring up an interactive bash shell session with a clean environment using env -i bash at any time. There is no point in doing it from ~/.bash_profile by default. I believe this was what user muru alluded to, but with different words. – Kusalananda Oct 28 '19 at 22:02
  • @Israr Sorry, I have no idea what you're replying to because, as is now common, my comment has simply disappeared. Not your fault. I give up on this dead platform. The moderators are now just making everything worse. Not sure what they get out of it... – Lightness Races in Orbit Oct 29 '19 at 01:34
  • @LightnessRaceswithMonica There was a comment that a user flagged as unkind, so a moderator deleted it. Was that the wrong thing to do? – Kusalananda Oct 29 '19 at 07:12
  • user @muru's comment also got deleted. – Israr Oct 29 '19 at 08:37
  • Befor accepting the answer 2 points i want to make : (1) Line in ~/.bash_profile is to make a clean environment, which we all agree at some extent. (2) Suitable location for PS1 is ~/.bashrc. – Israr Oct 29 '19 at 08:54
  • @IsrarSayed There were a couple of comments depended on a flagged comment. Comments are primarily for asking about clarifications or suggesting improvements to answers or questions. They are by their nature transient. Your points seems correct, although creating a clean environment from ~/.bash_profile for all one's shells seems counterproductive, as it deletes environment variables set up by system initialization files in /etc. – Kusalananda Oct 29 '19 at 09:10
  • @Kusalananda : But, my question and purpose is a little special, for a CLFS build from scratch to a bootable system, one cant afford a potential variable comes in between a long build and trumble it, leaving almost no clue.I had previous experiances.Yes , I completely agree for a general scenario, you are correct. – Israr Oct 29 '19 at 09:41
5

To quote from the bash man page:

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 /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.

So it very much depends on how you start the shell.

  • If you want to have your PS1 active in all login shells (e.g. via su - <user> or when logging in remote via ssh), put it in profile.
  • If you want to have your PS1 active in all non-login shells (e.g. simply opening another terminal in your desktop environment), put in in bashrc.
  • If you want to have it active in both cases, you will need to put it in both files, or (which some Linux flavours do at least in the case of the system-wide /etc/profile and /etc/bash.bashrc), source the .bashrc in the .profile.
AdminBee
  • 22,803
1

PS1 should be in .bashrc. You could also set it in .profile.

Debian sources .bashrc from there:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi
markgraf
  • 2,860