bash .profile portability

bash .profile portability

Post by Murray Stoke » Wed, 19 Feb 1997 04:00:00



     I like to have a consistent user interface on all the diferent servers I
work on, however I've never taken the time to learn much about shell programming
(Perl does all that).  But I'd like to be able to add just a few lines to my
profile so that I can setup a different prompt if the host is running BASH
1.14, BASH 2.0, or a generic Bourne shell.  How can I use an if statement in the
.profile attached to branch to different sections of the initialization
depending on which shell or shell version is actualy present?  Any help would be
appreciated.

#
# Global Data and Environment Variables
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/home/murray/bin:.
EDITOR=/usr/local/bin/emacs
COLUMNS=80
LINES=25
TZ=EST
HISTFILE=
export PATH EDITOR COLUMNS LINES TZ HISTFILE

#
# Set up some alias' to make life easier
#
alias ls='ls -Fal'
alias untgz='tar zxvf'
alias error='tail -20 ~www/server/logs/error_log'

# make the phat prompt

PS1="\n [0;31m\d  [1m\t [0;31m $TZ\n [1;30m[ [0m\! [1m] [37m \w [0m:"

echo
echo Bash version $BASH_VERSION running on $OSTYPE $HOSTTYPE


http://www.cdrom.com/pub/artpacks

 
 
 

bash .profile portability

Post by Icarus Spar » Wed, 19 Feb 1997 04:00:00




>     I like to have a consistent user interface on all the diferent
>servers I work on, however I've never taken the time to learn much
>about shell programming (Perl does all that). But I'd like to be able
>to add just a few lines to my profile so that I can setup a different
>prompt if the host is running BASH 1.14, BASH 2.0, or a generic Bourne
>shell. How can I use an if statement in the .profile attached to branch
>to different sections of the initialization depending on which shell or
>shell version is actualy present? Any help would be appreciated.

Well, you can use 'if', but it would be better to use 'case'.

case "$BASH_VERSION" in
        1*) PS1='bash1 \$ ' ;;
        2*) PS1='bash2 \$ ' ;;
        *)  PS1='The one true shell $ ' ;;
esac

Icarus

 
 
 

bash .profile portability

Post by Murray Stoke » Thu, 20 Feb 1997 04:00:00


    Thanks, I found some documentation on the case statement.  But how can I
determine what shell is being run.  I'd like to build one master .profile script
for the Korn shell (and its different versions), good old sh, and bash.  I could
write another case statement easy enough, but what variables exist to determine
what shell it is.  Using the filename isn't a very accurate method to accomplish
that.

Quote:>Well, you can use 'if', but it would be better to use 'case'.

>case "$BASH_VERSION" in
>    1*) PS1='bash1 \$ ' ;;
>    2*) PS1='bash2 \$ ' ;;
>    *)  PS1='The one true shell $ ' ;;
>esac


http://www.cdrom.com/pub/artpacks
 
 
 

bash .profile portability

Post by Andreas Schw » Thu, 20 Feb 1997 04:00:00


|> case "$BASH_VERSION" in
|>   1*) PS1='bash1 \$ ' ;;
|>   2*) PS1='bash2 \$ ' ;;
|>   *)  PS1='The one true shell $ ' ;;
|> esac

Aha, Bash 3.0 will then be the one true shell :-)
--
Andreas Schwab                                      "And now for something

 
 
 

bash .profile portability

Post by Brian S Hil » Fri, 21 Feb 1997 04:00:00


: I like to have a consistent user interface on all the diferent servers I
: work on, however I've never taken the time to learn much about shell
: programming (Perl does all that).  But I'd like to be able to add just
: a few lines to my profile so that I can setup a different prompt if the
: host is running BASH 1.14, BASH 2.0, or a generic Bourne shell.  How
: can I use an if statement in the
: .profile attached to branch to different sections of the initialization
: depending on which shell or shell version is actualy present?  Any help
: would be appreciated.

The previous respondents' solutions should be sufficient for you, but here
is a solution for the general case (even for csh-like shells.)

Make files named ".prompt.BASH_1X", ".prompt.BASH_2X", and
".prompt.SH", and as many other files (and/or links!) as desired for
other shells (see the code below.)

file .prompt.BASH_1X:
PS1='bash1 $ ' exec /usr/local/bin/bash1        # or whatever path
--

file .prompt.BASH_2X:
PS1='bash2 $ ' exec /usr/local/bin/bash2        # or whatever path
--

file .prompt.SH:
PS1='sh $ ' exec /bin/sh
--

You could even do this in .prompt.CSH:
set prompt = 'csh % '
exec /bin/csh
--

Execute "whichshell" below as the last line of .profile or .login with
arguments:

whichshell .prompt

The prompt will be automatically set for any shell with a file/link named
.prompt.<shell>. Make sure to set a default prompt in the unlikely case that
"whichshell" can't determine which shell it's been invoked by.
--

# whichshell 2>&- || shtype=SH_OLD : do _not_ eliminate this comment line!
#*TAG:53722 8:Feb 11 1997:0755:sh.d/whichshell:whichshell:


#
# Suppose one desires a script be run regardless of knowledge of shell type,
# or that different versions of such script be run depending on the features
# of that shell version (instead of programming for the lowest common denom-
# inator), or simply wish to know the shell name and version currently running.
# This can serve as a "meta-shell" on top of just such a situation, instead
# of providing multiple scripts or relying on the value of the variable SHELL.
#
# usage:
#       whichshell [script [parameter(s)]]
#
#       With no arguments, the determined value of <shell> is printed
#       to stdout. If this cannot be determined, $SHELL is assumed if
#       set and non-null, otherwise string "UNKNOWN". With <script>
#       argument and optional <parameter(s)>, the script <script>.<shell>
#       is sourced with its positional parameters set to <parameter(s)>.
#
# example:
#       csh -f whichshell ./script p1 p2 p3
#       ksh whichshell ./script p1 p2 p3
#       sh whichshell ./script p1 p2 p3
#
#       It is assumed that files "./script.{CSH,KSH_88,SH}" exist
#       having valid csh, ksh[88], and sh code, respectively. One
#       may create links "script.SH" and "script.KSH_88" that point to
#       "script.KSH_93", and a link "script.CSH" to a "script.TCSH".
#
# return value:
#       For the case of no arguments:
#               0 if the shell is able to be determined, else 1.
#       else,
#               if the sourced file does not exist: 1, else the same
#               as above, unless there is an explicit "exit" therein.
#
# knows bash 1.x/2.x, csh, ksh 86/88/93, old sh, posix sh, sh, tcsh, and zsh.
# this script cannot be sourced; it must be executed within a subshell.
# positional parameters cannot have embedded whitespace or special characters.
# comments indicate the latest shell version tested, on the OS indicated.
# bash 1.x may attempt to source $ENV script meant for ksh or other shells.
# to be truly robust for very old sh's: eliminate all comments but the first.
# TO DO: pdksh; differentiate between zsh 2.x and zsh 3.x ?

#1 LEAST COMMON DENOMINATOR
unset a || shtype=SH_OLD                # ignore potential error message
set a = "$*"
test "$a" = "$*" && goto CSH

#2 BOURNE FAMILY
case $3 in
'')     shcmd='echo ' ;;
*)      set -- $3
        shcmd=". ${1:?}."
        shift ;;
esac
LINENO= RANDOM= a=$[1] retval=0
a=2 a=$[3] wait 2>&-
case $a$LINENO:$RANDOM in
1*)     if (: ${!a}) 2>&-
        then    shtype=BASH_2X          # bash 2.00 (IRIX 5.x)
        else    shtype=BASH_1X          # bash 1.14.7(2) (IRIX 5.x)
        fi ;;
$\[3]:[0-9]*)
        shtype=KSH_86 ;;                # ksh 6/3/86
$\[3][0-9]*)
        shtype=KSH_88 ;;                # ksh 11/16/88f-beta4 (IRIX 5.x)
$\[1][0-9]*)
        # some ksh88s are modified to apparently conform to POSIX 1003.2
        if (: ${.sh.version}) 2>&-
        then    shtype=KSH_93           # ksh M-12/28/93e (IRIX 5.x)
        else    shtype=KSH_88           # ksh 11/16/88f (AIX 4.x, OSF/1 3.x)
                #shtype=KSH_88POSIX     # ksh 11/16/88f (AIX 4.x, OSF/1 3.x)
        fi ;;
$\[3]:) shtype=SH_POSIX ;;              # sh SVR4 (Unixware)
2:)     case $shtype in
        SH_OLD) ;;                      # sh (V7, BSD4.x, Ultrix)
        *)      if (_(){ :;}) 2>&-
                then    shtype=SH       # sh SVR2/3
                else    shtype=SH_OLD
                fi ;;
        esac ;;
3*)     shtype=ZSH ;;                   # zsh 2.3.1 (IRIX 5.x)
*)      retval=1 shtype=`
                IFS=/
                set -- ${SHELL:-UNKNOWN}
                until test \$# = 1
                do      shift
                done
                echo "\$1"
        ` ;;
esac
eval $shcmd$shtype
exit $retval

#3 CSHELL FAMILY
CSH:
if ("X$a" == X) then
        set shcmd = 'echo '
else
        set argv = ($a) shcmd = "source $1."
endif
set a = /b/c.d.e retval = 0
switch ($a:t:r:e)
case c:d:e:r:e:                         # csh (SunOS 4.x)
case c.d.e:r:e:                         # csh (IRIX 5.x)
        set shtype = CSH
        breaksw
case d:
        set shtype = TCSH               # tcsh 6.04 (IRIX 5.x)
        breaksw
default:
        if ! ($?shell) set shell = UNKNOWN retval = 1
        if ("X$shell" == X) set shell = UNKNOWN retval = 1
        set shtype = $shell:t
        breaksw
endsw
eval $shcmd$shtype
exit $retval
--

-Brian
--
   ,---.     ,---.     ,---.     ,---.     ,---.     ,---.     ,---.  
  /  _  \   /  _  \   /  _  \   /  _  \   /  _  \   /  _  \   /  _  \  

__,'   `.___,'   `.___,'   `.___,'   `.___,'   `.___,'   `.___,'   `.__

 
 
 

bash .profile portability

Post by Mohit Aro » Tue, 04 Mar 1997 04:00:00



>     Thanks, I found some documentation on the case statement.  But how can I
> determine what shell is being run.  I'd like to build one master .profile script
> for the Korn shell (and its different versions), good old sh, and bash.  I could
> write another case statement easy enough, but what variables exist to determine
> what shell it is.  Using the filename isn't a very accurate method to accomplish
> that.

Use 'echo $0' to determine which shell is being run.

- Mohit

 
 
 

bash .profile portability

Post by Brian S Hil » Wed, 05 Mar 1997 04:00:00


: Thanks, I found some documentation on the case statement.  But how can
: I determine what shell is being run.  I'd like to build one master
: .profile script for the Korn shell (and its different versions), good
: old sh, and bash.  I could write another case statement easy enough,
: but what variables exist to determine what shell it is.  Using the
: filename isn't a very accurate method to accomplish that.

I have a script that does just this; even csh-like user shells are recognized.

# whichshell 2>&- || shtype=SH_OLD : do _not_ eliminate this comment line!
#*TAG:53722 8:Mar 3 1997:0755:sh.d/whichshell:whichshell:


#
# Suppose one desires a script be run regardless of knowledge of shell type,
# or that different versions of such script be run depending on the features
# of that shell version (instead of programming for the lowest common denom-
# inator), or simply wish to know the shell name and version currently running.
# This can serve as a "meta-shell" on top of just such a situation, instead
# of providing multiple scripts or relying on the value of the variable SHELL.
#
# usage:
#       whichshell [script [parameter(s)]]
#
#       With no arguments, the determined value of <shell> is printed
#       to stdout. If this cannot be determined, $SHELL is assumed if
#       set and non-null, otherwise string "UNKNOWN". With <script>
#       argument and optional <parameter(s)>, the script <script>.<shell>
#       is sourced with its positional parameters set to <parameter(s)>.
#
# example:
#       csh -f whichshell ./script p1 p2 p3
#       ksh whichshell ./script p1 p2 p3
#       sh whichshell ./script p1 p2 p3
#
#       It is assumed that files "./script.{CSH,KSH_88,SH}" exist
#       having valid csh, ksh[88], and sh code, respectively. One
#       may create links "script.SH" and "script.KSH_88" that point to
#       "script.KSH_93", and a link "script.CSH" to a "script.TCSH".
#
# return value:
#       For the case of no arguments:
#               0 if the shell is able to be determined, else 1.
#       else,
#               if the sourced file does not exist: 1, else the same
#               as above, unless there is an explicit "exit" therein.
#
# knows bash 1.x/2.x, csh, ksh 86/88/93, old sh, posix sh, sh, tcsh, and zsh.
# this script cannot be sourced; it must be executed within a subshell.
# positional parameters cannot have embedded whitespace or special characters.
# comments indicate the latest shell version tested, on the OS indicated.
# bash 1.x may attempt to source $ENV script meant for ksh or other shells.
# to be truly robust for very old sh's: eliminate all comments but the first.
# TO DO: pdksh; differentiate between zsh 2.x and zsh 3.x ?

#1 LEAST COMMON DENOMINATOR
unset a || shtype=SH_OLD                # ignore potential error message
set a = "$*"
test "$a" = "$*" && goto CSH

#2 BOURNE FAMILY
case $3 in
'')     shcmd='echo ' ;;
*)      set -- $3
        shcmd=". ${1:?}."
        shift ;;
esac
LINENO= RANDOM= a=$[1] retval=0
a=2 a=$[3] wait 2>&-
case $a$LINENO:$RANDOM in
1*)     if (: ${!a}) 2>&-
        then    shtype=BASH_2X          # bash 2.00 (IRIX 5.x)
        else    shtype=BASH_1X          # bash 1.14.7(2) (IRIX 5.x)
        fi ;;
$\[3]:[0-9]*)
        shtype=KSH_86 ;;                # ksh 6/3/86
$\[3][0-9]*)
        shtype=KSH_88 ;;                # ksh 11/16/88f-beta4 (IRIX 5.x)
$\[1][0-9]*)
        # some ksh88s are modified to apparently conform to POSIX 1003.2
        if (: ${.sh.version}) 2>&-
        then    shtype=KSH_93           # ksh M-12/28/93e (IRIX 5.x)
        else    shtype=KSH_88           # ksh 11/16/88f (AIX 4.x, OSF/1 3.x)
                #shtype=KSH_88POSIX     # ksh 11/16/88f (AIX 4.x, OSF/1 3.x)
        fi ;;
$\[3]:) shtype=SH_POSIX ;;              # sh SVR4 (Unixware)
2:)     case $shtype in
        SH_OLD) ;;                      # sh (V7, BSD4.x, Ultrix)
        *)      if (_(){ :;}) 2>&-
                then    shtype=SH       # sh SVR2/3
                else    shtype=SH_OLD
                fi ;;
        esac ;;
3*)     shtype=ZSH ;;                   # zsh 2.3.1 (IRIX 5.x)
*)      retval=1 shtype=`
                IFS=/
                set -- ${SHELL:-UNKNOWN}
                until test \$# = 1
                do      shift
                done
                echo "\$1"
        ` ;;
esac
eval $shcmd$shtype
exit $retval

#3 CSHELL FAMILY
CSH:
if ("X$a" == X) then
        set shcmd = 'echo '
else
        set argv = ($a) shcmd = "source $1."
endif
set a = /b/c.d.e retval = 0
switch ($a:t:r:e)
case c:d:e:r:e:                         # csh (SunOS 4.x)
case c.d.e:r:e:                         # csh (IRIX 5.x)
        set shtype = CSH
        breaksw
case d:
        set shtype = TCSH               # tcsh 6.04 (IRIX 5.x)
        breaksw
default:
        if ! ($?shell) set shell = UNKNOWN retval = 1
        if ("X$shell" == X) set shell = UNKNOWN retval = 1
        set shtype = $shell:t
        breaksw
endsw
eval $shcmd$shtype
exit $retval
--

Examples:
$ whichshell    # my home shell is...
KSH_93
$ ENV= bash whichshell
BASH_1X
$ sh whichshell
SH
$ csh whichshell        # do you have any idea how hard it is to write a
CSH                     # script that will run in csh _and_ sh?

Now, make files .init.SH, .init.BASH_1X, and .init.KSH_88 (and .init.CSH ?)

.init.SH:
# bourne shell specific initializations, etc, here...
exec /bin/sh -i
--

.init.KSH_88:
# ksh shell specific initializations, etc, here...
exec /bin/ksh -i
--

.init.BASH_1X:
# bash specific initializations here...
exec /bin/bash -i
--

.init.CSH:
# csh specific initializations here...
exec /bin/csh -i
--

Each users .profile (or .login) should have _one_ line of the form:

/path/to/whichshell .init

User modifications can be done in the .init.xxx file. There, it's done.

P.S. Did I not answer this question before?

-Brian
--
   ,---.     ,---.     ,---.     ,---.     ,---.     ,---.     ,---.  
  /  _  \   /  _  \   /  _  \   /  _  \   /  _  \   /  _  \   /  _  \  

__,'   `.___,'   `.___,'   `.___,'   `.___,'   `.___,'   `.___,'   `.__

 
 
 

1. BASH BASH BASH BASH BASH BASH BASH BASH BASH BASH

Is there a proper fixed bash on any of the FTP sites out there?

I know there bash is on the usual sites but I don't know if they are
bugged or not :(

Regards,

Neil.

--


------------------------------------| Edinburgh, EH14 2DE, United Kingdom
**Domino: There`s nothing you can do when you`re the next in line: Domino**

2. PPPoE and Earthlink DSL

3. changing bash profile into csh profile?

4. X start at boot up

5. Help Me Set Bash Profile

6. Sample Smail 3.1.29 config?

7. BASH: how to interrupt .profile with cntl-c?

8. Invisible cursor in curses ?

9. Bash doesn't trap cntl-c while reading .profile

10. bash .profile questions

11. Bash profile not read at xterm startup

12. Can't locate .profile, .login files on bin/bash dial-up shell?

13. bash and .profile