LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (http://www.linuxquestions.org/questions/slackware-14/)
-   -   Default prompt in non-login shells (http://www.linuxquestions.org/questions/slackware-14/default-prompt-in-non-login-shells-4175447920/)

dragon_cb_cz 01-30-2013 10:11 PM

Default prompt in non-login shells
 
I know this issue has been debated many times over here, but I think my question is a bit different and I was unable to find an answer for it.

Long story short, by default I get this default prompt in xterm or any other terminal emulator that I launch in X11:
Code:

bash-4.1$
I know that to change it, I need to set PS1 in my ~/.bashrc - that's not a problem. What boggles my mind is that PS1 is clearly set in /etc/profile
Code:

PS1='\u@\h:\w\$ '
...
export PATH DISPLAY LESS TERM PS1 PS2

I know that /etc/profile only gets sourced for login shells, but I always thought /etc/profile sets environment that is inherited for example in X11 sessions. The fact that there are many variables set in /etc/profile.d/*.sh (those get sourced in /etc/profile) that are present in my environment - like XDG_CONFIG_DIRS and friends - IMHO supports this theory. For some reason, PS1 isn't one of them.

Does anyone know the reason for this weird behavior? I have already ruled out KDM, since it happens even when I switch to runlevel 3 and launch X11 via "startx". It seems that (at least part of) my environment gets wiped when X starts - becaus PS1 is correctly set (and exported) in the console session.

Any ideas? I'm running Slack 13.37 on this machine, but IIRC I have the same behaviour on my laptop that runs 14.0 - can check tomorow if it helps.

T3slider 01-31-2013 01:16 AM

Some bash(/shell)-specific variables are not inherited. PS1 is local to an instance of the terminal, as is TERM. I don't have a list of variables but those are the two most obvious ones. There isn't much you can do about it since they are instance-specific -- just set PS1 (and PS2-4 if you need to) in .bashrc instead of .bash_profile, and set other non-instance-specific variables in .bash_profile (or /etc/profile{,.d}) as needed.

PS1 being set in /etc/profile just gives real login shells (VTs) a PS1 default.

saulgoode 01-31-2013 04:36 AM

Quote:

Originally Posted by dragon_cb_cz (Post 4881041)
... I always thought /etc/profile sets environment that is inherited for example in X11 sessions. The fact that there are many variables set in /etc/profile.d/*.sh (those get sourced in /etc/profile) that are present in my environment - like XDG_CONFIG_DIRS and friends - IMHO supports this theory. For some reason, PS1 isn't one of them.

Technically speaking, PS1 is not an "environment" variable; it is a "shell" variable. Therefore it is not inherited (if you remove the line in ~/.bashrc that sets PS1, the default value will be used).

The 'env' command shows both environment variables and shell variables. You can see just the environment variables with the 'printenv' command. I don't know how to list just the shell variables.

GazL 01-31-2013 05:18 AM

As soon as /etc/profile exports PS1 it becomes an environment variable and will be inherited by child-processes. Try starting something like ash/ksh from a bash-login shell and you'll see it completely mess up when it tries to interpret the incompatible bash specific PS1 string it inherits.

Exporting PS1 is a mistake.and is something I've commented on before, and is why I remove the export of PS1 from my /etc/profile and use ~/.bashrc to set the bash specific prompt.


Why your X may not be inheriting an exported PS1 isn't really clear, but probably the result of something doing some form of sanitisation on the environment, but exactly what is happening may depend on how you're starting and logging into X, and what if anything the terminal program is doing to its environment before launching bash.

dragon_cb_cz 01-31-2013 08:44 AM

Quote:

Originally Posted by T3slider (Post 4881112)
Some bash(/shell)-specific variables are not inherited. PS1 is local to an instance of the terminal, as is TERM.

This is not true - if I launch an xterm instance, export PS1='whatever' and then launch another xterm instance from the first one, it inherits PS1 correctly.

Quote:

Originally Posted by saulgoode
Technically speaking, PS1 is not an "environment" variable; it is a "shell" variable. Therefore it is not inherited

As said by GazL, it's exported and therefore should be an environment variable.

Quote:

Originally Posted by GazL
As soon as /etc/profile exports PS1 it becomes an environment variable and will be inherited by child-processes. Try starting something like ash/ksh from a bash-login shell and you'll see it completely mess up when it tries to interpret the incompatible bash specific PS1 string it inherits.

Exporting PS1 is a mistake.and is something I've commented on before, and is why I remove the export of PS1 from my /etc/profile and use ~/.bashrc to set the bash specific prompt.

OK, point taken. It's just that nobody but me uses this machine, so it felt natural to set all this stuff system-wide (I don't use other shell than bash either), but no problem, moved to ~/.bashrc.

I'm almost sure it wasn't like this in earlier slackware versions, but I've been ignoring the default prompt for so long I can't remember when it first appeared. No idea when this environment sanitization was introduced, but when googling for solutions, often-suggested "solution" is to source /etc/profile in ~/.bashrc - so much for sanitization :/ I guess this could be considered a bug and the relevant bits should be moved from /etc/profile to a skeleton .bashrc?

tronayne 01-31-2013 09:14 AM

I don't know if this is really going to be relevant here but this is what I do (I don't use BASH at all, preferring KornShell).

In /etc/profile.d I have a file ksh.sh which contains:
Code:

cat /etc/profile.d/ksh.sh
#!/bin/sh
#ident        "$Id$"
#
#        Name:                $Source$
#        Version:        $Revision$
#        Modified:        $Date$
#        Purpose:        set local environment variables for Korn Shell
#        Author:                T. N. Ronayne
#        Date:                1 Oct 2009
#        $Log$
# Set the HOST environment variable
export HOST="`uname -n`"
# Set ksh93 visual editing mode:
if [ "$SHELL" = "/bin/ksh" ]; then
#  VISUAL=emacs                # ugh
#  VISUAL=gmacs                # double ugh
  VISUAL=vi                # ah, elegence
fi
# Set a default shell prompt:
#PS1='`hostname`:`pwd`# '
# Do these anyway in case sombody uses a different shell
if [ "$SHELL" = "/bin/pdksh" ]; then
 PS1='! $ '
elif [ "$SHELL" = "/bin/ksh" ]; then
 PS1='${HOST}-${USER}-${PWD}: '
elif [ "$SHELL" = "/bin/zsh" ]; then
 PS1='%n@%m:%~%# '
elif [ "$SHELL" = "/bin/ash" ]; then
 PS1='$ '
else
 PS1='\u@\h:\w\$ '
fi
PS2='> '
export PS1 PS2

What this does is overlay what's in /etc/profile (I do not ever edit profile, I use the shell program in profile.d to control environment variables). With this, all user prompts are similar to
Code:

fubar-trona-/home/trona:
I also have, in every user home directory a file .kshrc:
Code:

cat .kshrc
alias lc='/usr/bin/clear; /bin/ls ${LS_OPTIONS} -aCF'
alias ll='/bin/ls ${LS_OPTIONS} -al'
alias cls='clear'
alias hi='history -${LINES}'
alias rs='eval `resize`'

which sets a couple of aliases (and individual users are free to change that however they prefer).

Additionally, every user account has a .profile file that sets up some other stuff:
Code:

cat .profile
#        set up default columns and lines
COLUMNS=80
LINES=40
export COLUMNS LINES
#        set up default group
GRPNAME=`groups | cut -d' ' -f1`
export GRPNAME
#        set up a good-size history
HISTSIZE=1000
export HISTSIZE
#        set up the ksh environment
ENV=${HOME}/.kshrc
export ENV
#        set up CVSROOT
CVSROOT=:pserver:trona@fubar.com:/usr/local/cvsroot
export CVSROOT
#        change the PATH a little
export PATH=.:${HOME}/bin:${PATH}
export INSTALL_BASE=${HOME}
export LLDATABASES=${HOME}/LifeLines:.
export LLPROGRAMS=.:/usr/local/share/lifelines
#        make COLUMNS and LINES the screen size
eval `resize`

You log in, you get /etc/profle, /etc/profile.d/ksh.sh, ${HOME}/.profile and ${HOME}/.kshrc (and $HOME}/.exrc which sets some variables for vi). Those only execute once at login as opposed to environmental files in, say, C-Shell which execute every time you hit the carriage return (and, I think, some of those in BASH do the same thing).

The real trick is to simply set the terminal emulator program to be a login shell and you get all the nice environment stuff (that works in KDE and Xfce); in an Xfce terminal, click Edit, Preferences, General and the box for Run command as login shell (don't remember what to do in in KDE but it's in there too).

Hope this helps some.

dragon_cb_cz 01-31-2013 09:52 AM

Quote:

Originally Posted by tronayne (Post 4881346)
The real trick is to simply set the terminal emulator program to be a login shell and you get all the nice environment stuff (that works in KDE and Xfce); in an Xfce terminal, click Edit, Preferences, General and the box for Run command as login shell (don't remember what to do in in KDE but it's in there too).

Hope this helps some.

This is exactly what I was traying to avoid though. I could obviously launch "xterm -ls" instead of just xterm to make it a login shell. That, however, is fundamentally wrong (at least in Slackware) since then you get many of the variables set twice, for example:
Code:

CPLUS_INCLUDE_PATH=/usr/lib64/qt/include:/usr/lib64/qt/include
MANPATH=/usr/local/man:/usr/man:/usr/lib64/java/man:/usr/lib64/java/man:/usr/share/texmf/man
PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/local/lib64/pkgconfig
XDG_CONFIG_DIRS=/etc/xdg:/etc/kde/xdg:/etc/xfce/xdg:/etc/kde/xdg:/etc/xfce/xdg

See those duplications? Also, running everything in /etc/profile and /etc/profile.d/*.sh every time I open an xterm (sometimes I do that quite often, several times per minute) isn't exactly what I'm after. Also, it emits fortune message to every xterm I open - quite annoying (albeit easy to solve).

GazL 01-31-2013 09:54 AM

Quote:

Originally Posted by dragon_cb_cz (Post 4881330)
but when googling for solutions, often-suggested "solution" is to source /etc/profile in ~/.bashrc

Yep, I see that suggestion quite often too and IMO it is the wrong way around. /etc/profile is intended to run things that only need to be done once.

IMO, better to source ~/.bashrc from /etc/profile or ~/.bash_profile (which is what I do)

~/.bash_profile:
Code:

case $- in
*i* )  # Interactive shell
      if [ -f ~/.bashrc ]; then
          source ~/.bashrc
      fi
      ;;
esac

or if you want to do it system wide, something like
/etc/profile.d/bashrc.sh:
Code:

if [ "$BASH_VERSION" ] ; then
  case $- in
  *i* )  # Interactive shell
          if [ -f ~/.bashrc ]; then
            source ~/.bashrc
          fi
          ;;
  esac
fi


dragon_cb_cz 01-31-2013 05:25 PM

Quote:

Originally Posted by GazL (Post 4881380)
Yep, I see that suggestion quite often too and IMO it is the wrong way around. /etc/profile is intended to run things that only need to be done once.

Yep, it's completely wrong, that's why I wanted to avoid it and also didn't want to launch "xterm -ls" to get a login shell. I still have the feeling this part of Slackware is a bit messed up, but who am I to judge :scratch:


All times are GMT -5. The time now is 07:43 PM.