: 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
--
,---. ,---. ,---. ,---. ,---. ,---. ,---.
/ _ \ / _ \ / _ \ / _ \ / _ \ / _ \ / _ \
__,' `.___,' `.___,' `.___,' `.___,' `.___,' `.___,' `.__