LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (https://www.linuxquestions.org/questions/slackware-14/)
-   -   Why does PS1 get unset when I run X Windows / KDE? (https://www.linuxquestions.org/questions/slackware-14/why-does-ps1-get-unset-when-i-run-x-windows-kde-4175701022/)

emmet 09-23-2021 06:37 PM

Why does PS1 get unset when I run X Windows / KDE?
 
So today was a day of reckoning. I finally grew sufficiently weary of being reminded by every shell prompt in Xfce Terminal or Konsole that I was running bash-5.1 to actually do something about it. So after a bit of fumbling about and relearning for the nth time the difference between .bash_profile and .bashrc, I got the perfectly cromulent bash prompt that I already had in the console by default.

What did I do in .bashrc? I assigned a value to PS1 and exported that assignment:

#!/bin/bash
export PS1='\u@\h:\w\$ '

Issue solved. But why did I have this issue?

PS1 gets defined and exported in /etc/profile. That definition endures all the trials and tribulations of console life, but when I run startx (runlevel 3 rules!) PS1 gets crushed. Why the PS1 hate in the gui? Is this some kind of anti-terminal bias? Why has my terminal emulator been having to deal with a hostile work environment? This terminal emulator is now safe. Going forward, PS1 is always going to be there. But what about all the other terminal emulators out there? Why does PS1 get unset?

rkelsen 09-23-2021 08:44 PM

PS1 doesn't "get unset."

The reason for your problem is that terminal emulators like Konsole are configured to not open a new login shell every time, which is why they seem to ignore /etc/profile.

You can work around this a few different ways, one of which is shown in this post: https://www.linuxquestions.org/quest...ml#post6277664

Essentially, you need to tell your terminal emulator to run "/bin/bash -l" at startup. The "-l" ensures that it makes bash behave as if it were invoked a login shell, thereby honouring your settings in /etc/profile.

If you want to try it, you can open a terminal and run "/bin/bash -l" to verify that it works acceptably before you make any changes:
Code:

$ /bin/bash -l
me@here:/$


emmet 09-23-2021 09:39 PM

Quote:

Originally Posted by rkelsen (Post 6286489)
PS1 doesn't "get unset."

I must demur. PS1 gets unset. In the console, my login shell, running "env|grep PS1" displays the value assigned to PS1. PS1 is an exported environmental variable. Just like PATH. Yet when I open a terminal emulator in the gui, and run env, PS1 is gone but PATH is still there. Why did PATH make it but PS1 did not? There is a long list of exported environmental variables that successfully get passed on, parent to child, that make that generational journey from the login console shell to the terminal emulator running in the gui. PS1 is an exception to that rule. It's getting squashed somewhere along the way, silently deleted from the environment so that it is as if it was never there. Who will speak for PS1?

Quote:

Essentially, you need to tell your terminal emulator to run "/bin/bash -l" at startup. The "-l" ensures that it makes bash behave as if it were invoked a login shell, thereby honouring your settings in /etc/profile.
PATH is set in /etc/profile, just like PS1. But I don't need to pass bash a -l to persuade it to accept the inherited environmental variable PATH. And if I don't pass -l to bash, and it does not therefore execute /etc/profile, then the PATH setting that it uses must be the exported value that it inherited from its parent, which was in turn originally inherited from the login shell, which did execute /etc/profile. That's how environmental variables work. It takes an effort to make them work otherwise. PS1 did not just wander off. It was eliminated.

With your -l, you are giving me another way to treat the symptom. I have already treated the symptom. I stuck the PS1 definition in ~/.bashrc. Symptom treated. I am asking for the cause.

I suspect it is Bash itself that is expurgating the inherited environmental variable PS1.

rkelsen 09-24-2021 12:42 AM

Quote:

Originally Posted by emmet (Post 6286496)
I must demur. PS1 gets unset. In the console, my login shell, running "env|grep PS1" displays the value assigned to PS1. PS1 is an exported environmental variable. Just like PATH. Yet when I open a terminal emulator in the gui, and run env, PS1 is gone but PATH is still there. Why did PATH make it but PS1 did not?

I get this (in Konsole running under KDE):
Code:

me@here:~$ env | grep PS1
PS1=\u@\h:\w\$
me@here:~$

My settings are stock, except for changing Konsole to run bash with the "-l" switch. I haven't touched anything in /etc/profile or .bashrc... in fact, my user account doesn't even have a .bashrc file.

rkelsen 09-24-2021 12:55 AM

This happens because your terminals are not opening login shells.

I found this information which might be useful for you:

"When you log in on a text console, or through SSH, or with su -, you get an interactive login shell. When you log in in graphical mode (on an X display manager), you don't get a login shell, instead you get a session manager or a window manager.

It's rare to run a non-interactive login shell, but some X settings do that when you log in with a display manager, so as to arrange to read the profile files. Other settings (this depends on the distribution and on the display manager) read /etc/profile and ~/.profile explicitly, or don't read them."


https://unix.stackexchange.com/quest...on-login-shell

pan64 09-24-2021 01:04 AM

ok, the correct answer is: PS1 get only "lost" if it was explicitly unset somewhere. It cannot disappear without reason. Or probably it was not set at all. Usually it is set in /etc/profile (or probably /etc/bash.bashrc, which is sourced from /etc/profile).
It looks like PS1 is not exported (at least for me), so will not be inherited.
you explained when you execute startx it will be missing, therefore you need to look around there. PS1 does not hate GUI, PS1 is actually very sad because cannot meet you.

emmet 09-24-2021 01:25 AM

No, I have not broken anything. I don't have a problem. Having added the PS1 definition to ~/.bashrc, I'm getting the prompt I wanted. PS1 is set as desired. I said that at the outset, in my first post.

Code:

emmet@dimholt:~$ echo $PS1
\u@\h:\w\$

What I have is a question. About Linux. The site is called LinuxQuestions.org.

The question is why is this particular environmental variable cleared while others are preserved. Why is it necessary to invoke bash as a login shell or populate ~/.bashrc with the PS1 definition, yet the same is not true for PATH? They were both initially set by the execution of the same script, /etc/profile. The definition of PATH endures without special intervention. The definition of PS1 does not. Why is that? That is my question. You have not addressed it. Rather, you have talked past it.

pan64 09-24-2021 01:45 AM

Not cleared. It is not exported, so even if it was set earlier it will not be inherited in shells. So the shells should take care of it by themselves. And that's why it was not set in a non-login interactive shell - which is used in terminal emulators. See man bash about invocation and about the init/rc files used in this case. That's why it can be put into ~/.bashrc.

emmet 09-24-2021 02:03 AM

Quote:

Originally Posted by pan64 (Post 6286514)
ok, the correct answer is: PS1 get only "lost" if it was explicitly unset somewhere. It cannot disappear without reason. Or probably it was not set at all. Usually it is set in /etc/profile (or probably /etc/bash.bashrc, which is sourced from /etc/profile).
It looks like PS1 is not exported (at least for me), so will not be inherited.
you explained when you execute startx it will be missing, therefore you need to look around there. PS1 does not hate GUI, PS1 is actually very sad because cannot meet you.

Yes, PS1 gets set when /etc/profile is run at login. That works. And it is exported. I have a stock slackware64-current /etc/profile, which contains the following line:

Code:

export PATH DISPLAY LESS TERM PS1 PS2
But once in KDE and in a terminal emulator, PS1 is no longer set. Neither is PS2, for that matter. I get the default bash prompt, not the prompt defined and exported in /etc/profile. So I added the PS1 definition to ~/.bashrc, and that solved the issue. As rkelsen pointed out, another way to solve the issue would be to coax the terminal emulator into invoking bash with a -l argument, instructing bash to run in login mode and thus execute /etc/profile and also ~/.bash_profile and ~/.profile if they exist (again). Either method would work. I went the ~/.bashrc route. It's one stop shopping. It fixes the bash prompt in any terminal emulator I use. (I'm currently on the fence between Xfce Terminal and Konsole.)

But as you pointed out, exported environmental variables do not unset themselves. And other than PS1 and PS2, none of the other environmental variables initially defined and exported by /etc/profile when I log in later become unset as far as I have noticed. Certainly, PATH endures unchanged. That would be noticeable. It's a phenomenon peculiar to these two. I suspect that bash is unsetting them. As far as I know, it's only the shell that ever uses PS1 and PS2, so it does not make sense that any other program would bother with them. But that is my question: what is stepping on PS1 (and PS2). I'm not asserting that there is a problem of any kind. I'm just curious as to what is going on. In the course of fixing the command line prompt, I just wondered, why does this need fixing? It's a small mystery.

pghvlaans 09-24-2021 02:17 AM

If I understand correctly, bash itself sets a default PS1 for interactive non-login shells. This default value is then superseded by whatever's in .bashrc.

emmet 09-24-2021 02:32 AM

Quote:

Originally Posted by pghvlaans (Post 6286527)
If I understand correctly, bash itself sets a default PS1 for interactive non-login shells. This default value is then superseded by whatever's in .bashrc.

That's the answer I was looking for. Thank you.

GazL 09-24-2021 06:15 AM

Slackware's stock /etc/profile exports PS1. However, that's a mistake, and one of the first things I fix after a clean install.

PS1 should be set in both /etc/profile and ~/.bashrc but not exported. Alternatively, to avoid duplication, have ~/.bash_profile source ~/.bashrc and just set the prompt in ~/.bashrc.

For the traditional UNIX shells, one would set PS1 in the file pointed to by $ENV, but bash only supports that when invoked as 'sh'. IMO it was a bad design choice to abandon this traditional behaviour, but bash is what it is.

Some folks go the "set the terminal to start a login shell" route, but I'm not a fan of that approach.

rkelsen 09-24-2021 06:37 AM

Quote:

Originally Posted by GazL (Post 6286557)
Some folks go the "set the terminal to start a login shell" route, but I'm not a fan of that approach.

Is there a technical reason for your position on this?

I'm quite keen to know.

GazL 09-24-2021 08:16 AM

Quote:

Originally Posted by rkelsen (Post 6286565)
Is there a technical reason for your position on this?

I'm quite keen to know.

Conceptually, login shells are intended for setting up the user's "session". When you login on a tty profile gets run, but any subsequent nested shells you run won't run it again. Now, in X11 that initial setup is done by Xsession/xinitrc.

There's a number of things you might want to be started when you login, such as gpg-agent, ssh-agent, etc that really shouldn't be started for any subsequent shell invocations in the same session. However, the most obvious example I can think of is that starting a login shell will mean .bash_logout gets run when it closes, which might not be what the user desires if they've got multiple terminal windows open. You could argue that this is no different than logging in on two console ttys at the same time of course, but IMO that's a more deliberate act than just popping open another terminal window on your desktop which people just do routinely without even thinking about it.

Another simple example is that a profile might do PATH=$PATH:/somewhere and you wouldn't want that run for every additional terminal window you pop-open as it would result in duplicates in the path.

Non of the above can't be worked around by careful construction of the profile/logout script logic of course, but I just find it conceptually cleaner to consider each new terminal shell a subcomponent of the X session rather than its own stand-alone session.

I'll stop short of telling others that starting a login shell in a terminal window is outright wrong: what's actually in the profile will have a bearing on the determination on that, but, conceptually I believe it to be the wrong approach.

As always, YMMV, it's just an opinion; though one I hold fairly strongly.

rkelsen 09-24-2021 11:46 PM

Quote:

Originally Posted by GazL (Post 6286581)
As always, YMMV, it's just an opinion; though one I hold fairly strongly.

Thanks!


All times are GMT -5. The time now is 09:35 AM.