LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices

Reply
 
Search this Thread
Old 08-05-2013, 04:11 PM   #1
GazL
Senior Member
 
Registered: May 2008
Posts: 3,425

Rep: Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937
Fixing shell prompts


Slackware's /etc/profile contains the following section relating to shell prompts:
Code:
# Set a default shell prompt:
#PS1='`hostname`:`pwd`# '
if [ "$SHELL" = "/bin/pdksh" ]; then
 PS1='! $ '
elif [ "$SHELL" = "/bin/ksh" ]; then
 PS1='! ${PWD/#$HOME/~}$ '
elif [ "$SHELL" = "/bin/zsh" ]; then
 PS1='%n@%m:%~%# '
elif [ "$SHELL" = "/bin/ash" ]; then
 PS1='$ '
else
 PS1='\u@\h:\w\$ '
fi
PS2='> '
export PATH DISPLAY LESS TERM PS1 PS2
There are a couple of problems with this approach. The first is that the value of $SHELL doesn't necessarily reflect the shell that is running the /etc/profile file. The second issue is that the PS1 and PS2 are exported, which means that if you were to start a non-login ksh or ash shell from within bash, or even a non-login bash shell from ksh they will inherit the incompatible shell prompt from the parent shell's environment and it won't display correctly.

While altering the code to use $0 rather than $SHELL and simply not exporting the PS1/2 would stop the incompatible inheritance issue, it would result in no inheritance at all and a default prompt in non-login shells (which IMO would still be a better choice than the brokenness we currently have but isn't ideal). To make everything nice and tidy I think the prompt stuff needs to be moved out of /etc/profile and into bashrc and equivalents for the other shells, which would make everything work as it should.


So, what I'm suggesting:

1) Remove the existing prompt setting code (including the export of PS1/2) from /etc/profile.

2a) Add a /etc/skel/.bash_profile (to run .bashrc for login-shells):
Code:
case $- in
*i* )  # Interactive shell
       if [ -f ~/.bashrc ]; then
          source ~/.bashrc
       fi
       ;;
esac
2b) Add a /etc/skel/.bashrc (to set PS1/2, aliases and/or optionally run a system wide /etc/bashrc):
Code:
[ -f /etc/bashrc ] && source /etc/bashrc

########################################################################

PS1='\u@\h:\w\$ '

alias ls='ls --color=auto --group-directories-first'
Then, to make something similar happen with the non-bash shells...
3a) Add a /etc/shinit file along the lines of:
Code:
# /etc/shinit  Shell environment file
#  
#  Shell environment file for tradition bourne family shells:
#    ash, ksh, pdksh, bash (when invoked with -posix or as 'sh').
#
#  To be invoked its path must be specifed in the 'ENV' 
#  environment variable.
#
#  Unlike /etc/profile, this file will also be invoked for
#  non-login shells and is therefore a good place to specify
#  aliases and PS prompts.
#  

case $- in
*i* )  # Ensure we only run in 'interactive' shells.
       case $0 in
       -pdksh|pdksh|*/pdksh)
                PS1='! $ '
                ;;
       -ksh|ksh|*/ksh)
                PS1='! ${PWD/#$HOME/~}$ '
                VISUAL=emacs      #  ksh93 Visual editing mode
                                  #    VISUAL=emacs|gmacs|vi
                ;;
       -sh|sh|*/sh|-ash|ash|*/ash)
                PS1='$ '
                ;;
       esac
       ;;
esac
(I've also incorporated the ksh93 VISUAL setting from /etc/profile into this so that can also be removed from /etc/profile.)

3b) Add the following to /etc/profile in order to make /etc/shinit run:
Code:
# Set Shell environment file for traditional bourne shell family:
#   ash, ksh, pdksh, bash (when invoked with -posix or as 'sh')
ENV='/etc/shinit'
export ENV
End result: each shell gets the correct prompt no matter whether it is a login or non-login shell or whether it is started from within a different shell type.

The only one I haven't included in this is zsh as I am unfamiliar with it's inner workings, but I suspect /etc/zshenv might be the correct place to set it's own PS1 in a similar manner.

If you only use bash, then the PS string stuff probably won't bother you, but moving the alias definitions to bashrc would have the advantage of making them available in non-login shells so there is still something to be gained.

Anyway, those are my thoughts and it's how I have my box configured at present.

Over to y'all for comments/suggestions...

Last edited by GazL; 08-05-2013 at 04:26 PM. Reason: 2b->3b
 
Old 08-06-2013, 06:44 AM   #2
adelabarra
Member
 
Registered: May 2008
Location: Argentina
Distribution: Debian, Slackware
Posts: 49

Rep: Reputation: 3
Dear GazL:
I use Slackware with xfce. (and kernel 2.6.10)
Don't know why when I enter the terminal from xfce, the prompt doesn't appear and I don't know where I am.
If I type export PS1= "\W", everything is OK.
How can I do to make it permanent?

Regards.

Alejandro.
 
Old 08-06-2013, 07:01 AM   #3
GazL
Senior Member
 
Registered: May 2008
Posts: 3,425

Original Poster
Rep: Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937
The safest bet is to add .bashrc and .bash_profile (as I described in 2a and 2b above) to your home directory. That way it should work in a desktop environment independent manner.
 
Old 08-06-2013, 09:12 AM   #4
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,075

Rep: Reputation: 777Reputation: 777Reputation: 777Reputation: 777Reputation: 777Reputation: 777Reputation: 777
All my systems are defaulted to KornShell (I just don't really care to use BASH) and terminals on all of them are configured as log in shells in Xfce (KDE is installed -- do like some of the utilities, don't like the overhead); matter of fact all shells are configured as log in shells no matter what window manger I use.

I do the prompt with a file, /etc/profile.d/ksh.sh (which is simply an edited part of /etc/profile):
Code:
#!/bin/sh
#
# 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, elegance
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
The above makes a terminal window prompt look like
Code:
fubar-trona-/home/trona:
and, because all systems are configured identically, I always know what box I'm on when connected with ssh to any one (or all) of them; one keyboard to rule them all, baby.

I also have, in each user home directory, .profile, .kshrc and .exrc. The .profile sets "useful" environment variables specific to the individual user:
Code:
fubar-trona-/home/trona: 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`
The COLUMNS and LINES are handy for curses forms; default to 80x40 (from the Goode Olde Days, that) and updated by the eval `resize` at the end; saves some trouble now and again. The other stuff are for compatibility with some specific work I do.

I also set, for me only, the current working directory as first on ${PATH} followed by my ${HOME}/bin; I'm well aware of the hazards of so doing and have been doing it for about 30 years and don't need any argument about it: It's my party and I'll cry if I want to.

~/.kshrc simply sets some aliases I like:
Code:
fubar-trona-/home/trona: 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`'
And ~/.exrc simply sets defaults that I like for vi:
Code:
fubar-trona-/home/trona: cat .exrc
set autoindent showmode showmatch
As far as I know, ${SHELL} gets set by login (from the log in shell in /etc/passwd) and is then used in /etc/profile so I don't see any problem with that. All the admin accounts are /bin/false (or special purpose like shutdown and halt, one or two others) and you're not supposed to be fiddling with those anyway so I don't see any problem there (you need to do some administration, you do it with su - far as I know and if you don't know what you're doing you shouldn't ought to be doing it anyway, eh?).

Defining terminal windows as log in shell does no harm -- you execute su -, you get root's environment. When you exit, you're back to your own environment (su - forks and executes in a new shell and when it exits that environment is gone). Simply demonstrated with
Code:
fubar-trona-/home/trona: su -
Password:
fubar-root-/root: whence -v ntpq
ntpq is a tracked alias for /usr/sbin/ntpq
fubar-root-/root: ^D
fubar-trona-/home/trona: whence -v ntpq
-ksh: whence: ntpq: not found
Same thing happens if you su - userid -- you get a forked-and-exec'd new shell, it is gone when you exit.

So, basically, I don't really see the problem with /etc/profile -- especially if you add custom files in /etc/profile.d, which, for example, would include things like Apache Ant, Apache Maven, Apache Tomcat, Java (jdk.sh and jdk.csh) and one that I add for the Generic Mapping Tools, gmt.sh, which sets environment variables for it -- that's what /etc/proifle.d is for, no need to mess with the default /etc/proifle (as in the Goode Olde Days when that was your only choice for system-wide settings).

Good thinking, but I'm not sure there's actually a problem.
 
1 members found this post helpful.
Old 08-06-2013, 09:52 AM   #5
GazL
Senior Member
 
Registered: May 2008
Posts: 3,425

Original Poster
Rep: Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937
Quote:
Originally Posted by tronayne View Post
A
As far as I know, ${SHELL} gets set by login (from the log in shell in /etc/passwd) and is then used in /etc/profile so I don't see any problem with that.
$SHELL does indeed get set by login, and it gets set to the value of the users default shell specified in /etc/passwd. The problem comes when you launch a login shell that is different to your default shell. For example having a default shell /bin/ksh, but then running "bash -l" from the ksh command-line after you login. 'bash -l' will run /etc/profile but $SHELL will still be '/bin/ksh' so it will be given the incompatible ksh PS1 string.

To be fair, this is probably a corner-case, as most people won't be using the -l option to start a login shell, and are especially unlikely to do so for a shells other than their default. I think the exporting of PS1/2 is what I object to most (but I guess that actually suits people who only ever use bash, though it does cause problems for the other shells).

I think that ideally I'd like to see /etc/profile not contain anything other than tradition 'sh' compliant stuff - even if this would mean having to stick with the less feature-full default '#' prompt out of the box.


Thanks for posting your setup. I found it interesting.

P.S. I'd forgotten about 'su', so using $0 rather than $SHELL isn't going to work in all situations either. I think the last time I looked at this stuff I ended up doing a test -n "$BASH_VERSION" to reliably identify a bash shell, but not all shells have a unique environment variable like that to select on. Given this added complexity, I think I'm leaning even more to not setting the prompt at all in /etc/profile and letting it default.

Last edited by GazL; 08-06-2013 at 10:00 AM.
 
Old 08-06-2013, 10:24 AM   #6
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,075

Rep: Reputation: 777Reputation: 777Reputation: 777Reputation: 777Reputation: 777Reputation: 777Reputation: 777
Huh.

Yup, see what you mean, but also see that it's highly unlikely that somebody would be switching back and forth (you learn one, the others are just unnecessary confusion -- think C-Shell here, what a mess that is). Absolutely, positively have to run a shell program in some other shell? That's what pound-bang is for, eh?.

There was (and still is) nothing wrong with Bourne, David Korn made it better (a lot better, IMHO). Berkeley went off in the blue somewhere or 'toher (what were those guys smoking when they came up with C-Shell?). BASH, well, Bourne + Korn + ... well, I dunno (and they seem to be unable to leave the damned thing alone!).

Anyway, getting off that tangent, some good thinking.

Last edited by tronayne; 08-06-2013 at 10:25 AM. Reason: Forgot the "un"
 
Old 08-06-2013, 11:09 AM   #7
GazL
Senior Member
 
Registered: May 2008
Posts: 3,425

Original Poster
Rep: Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937
I know what you mean about csh. Never got on with that.

Anyway, for the sake of completeness, here's a revised /etc/shinit that takes care of the '-su' issue it was missing before:

Code:
# /etc/shinit  Shell environment file
#  
#  Shell environment file for tradition bourne family shells:
#    ash, ksh, pdksh, bash (when invoked with -posix or as 'sh').
#
#  To be invoked its path must be specifed in the 'ENV' 
#  environment variable.
#
#  Unlike /etc/profile, this file will also be invoked for
#  non-login shells and is therefore a good place to specify
#  aliases and PS prompts.
#  

case $- in
*i* )  # Ensure we only run in 'interactive' shells.
       case "$0" in
           -pdksh|pdksh|*/pdksh) shell='pdksh' ;;
           -ksh|ksh|*/ksh) shell='ksh' ;;
           -ash|ash|*/ash) shell='ash' ;;
           -sh|sh|*/sh) shell='sh' ;;
           *) shell="${SHELL##*/}" ;;  # -su and any unknown shells.
       esac

       case "$shell" in
       pdksh)  PS1='! $ '
               ;;
       ksh)    PS1='! ${PWD/#$HOME/~}$ '
               VISUAL=emacs   #  ksh93 Visual editing mode
                              #    VISUAL=emacs|gmacs|vi
               ;;
       ash|sh) PS1='$ '
               ;;
       esac
       ;;
esac

unset shell
Whether making this work correctly is worth all the effort I'm not sure, but it's an interesting exercise.


BTW, While we're on the subject:
Any reason /bin/sh is not in /etc/shells?
 
Old 08-06-2013, 05:28 PM   #8
adelabarra
Member
 
Registered: May 2008
Location: Argentina
Distribution: Debian, Slackware
Posts: 49

Rep: Reputation: 3
Thanks to all!

I'll come back when I finish an try all this.

Regards.

Alejandro
 
Old 08-06-2013, 10:46 PM   #9
elyk
Member
 
Registered: Jun 2004
Distribution: Slackware
Posts: 164

Rep: Reputation: 23
+1 for not exporting $PS1 and $PS2.

+1 for providing a default .bash_profile and .bashrc, and for setting up .bash_profile to source .bashrc.

I assume that all of these shells set up their own default prompt if we leave $PS1 alone. Is there any reason why we override it globally? To me it seems like it should be set on a per-user basis, so in .bashrc or equivalent for their shell of choice.
 
Old 08-07-2013, 04:04 AM   #10
GazL
Senior Member
 
Registered: May 2008
Posts: 3,425

Original Poster
Rep: Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937Reputation: 937
The shells will default to their own prompt strings: most of which are not particularly helpful (e.g. bash uses "bash-4.2$"), but as I said in the first posting I'd rather have that than have the currently broken behavior we see from exporting PS1/2.

My guess is that they are overridden just to set a more useful system-wide default prompt, and exported so that they inherit down to child shells. Unfortunately this solution, though simple is a bit hit-n-miss and as shown above has side effects.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can I have Multiple shell prompts without a GUI? SquishyMarbles Linux - Software 6 10-25-2006 05:36 AM
general questions re shell, prompts, X carlos88 Linux - Newbie 1 07-23-2006 01:39 PM
Shell Scripts Answering Prompts dudeman41465 Linux - Software 1 01-24-2006 11:20 AM
Shell prompts and keymaps amnesty_puppy Linux - Newbie 8 08-17-2004 06:52 PM
Shell Prompts and root ls colouring iantri Slackware 10 09-11-2003 08:48 PM


All times are GMT -5. The time now is 10:18 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration