Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to distinguish between ksh88 & ksh93

40 views
Skip to first unread message

PH

unread,
Nov 15, 1999, 3:00:00 AM11/15/99
to
I work on both CDE and non-CDE platforms. To force the "dtksh"-shell (my
preferred shell) on CDE systems I perform an "exec /usr/dt/bin/dtksh" as
the last line in my .profile. That works fine, however, on systems that
do not support this shell (such as Silicon Graphics) some ksh93 builtins
I use in my .kshrc environment file such as "typeset -A" are not
recognized and will issue an error message. Also when I login on CDE
systems the login shell is still ksh88 causing the same error messages.
It's not a big deal but it would be nice to distinguish up-front between
a ksh88 and ksh93. I played with the $(.sh.version) parameter but that
is obviously not recognized in ksh88. Does anyone know a neat way to
support CDE (dtksh) and non-CDE (ksh88) platforms from the login
environment without introducing error messages.

-Paul


Dan Mercer

unread,
Nov 15, 1999, 3:00:00 AM11/15/99
to
In article <38300E2A...@siep.shell.com>,

The behavior of posix defined functions differs between ksh88 (pre-posix)
and ksh93. A posix defined function has the syntax:

identifier() { list; }

Ksh supports it'd own function definition syntax:

function identifier { list; }

In ksh88, both syntaxes have the same functionality and both support
local variables declared using the typeset command. In ksh93, the
posix syntax does not support local variables. So, to check which
version you are using:

check_version() { typeset version=ksh93; }
version=ksh88
check_version

# $version now contains ksh88 or ksh93 matching the version.

--
Dan Mercer
dame...@uswest.net


Opinions expressed herein are my own and may not represent those of my employer.


brian hiles

unread,
Nov 15, 1999, 3:00:00 AM11/15/99
to
Dan Mercer <dame...@mmm.com> wrote:
> In article <38300E2A...@siep.shell.com>,
> PH <p.p.h.v...@siep.shell.com> writes:
> check_version() { typeset version=ksh93; }
> version=ksh88
> check_version

To determine the version of a shell throughto existance of
non-existance of a bug is not the most robust way to do this.

I give you my script "whichshell" which you may use in your .profile
or strip out the pertainent criterion code, if you like. It has
the property of recognizing (and being run within) the csh shells.

# whichshell 2>&- || SHTYPE=SH_1977 : do NOT eliminate this first comment line!
#*TAG:48056 5:Nov 21 1998:0755:whichshell:
# Author: Brian Hiles <b...@iname.com>
# Copyright: (c) 1997-1998
# Description: determine which shell this script runs under
# Inspired-by: hei...@darwin.noris.de (Heiner Steven)
# Name: whichshell
# Sccs: @(#)whichshell.sh 1.2 1998/05 b...@iname.com (Brian Hiles)
# Usage: whichshell [script [script-parameter]...]
# Version: 1.02

#XXX consider allowing "init.KSH" instead of "init.KSH_19??"
#XXX SH_OLD -> SH_1977, etc.
#XXX SH_POSIX -> SH_199?
#XXX thoroughly document differences between early bourne shells in _man-page_

#01 COMMON CORE CODE
unset a || SHTYPE=SH_OLD # ignore potential error message
set a = "$*"
test "$a" = "$*" && goto CSH

#02 BOURNE FAMILY
PATH= export PATH
case $3 in
'') shcmd='echo ' ;;
*) set -- $3
shcmd=". ${1?}." # bash bug: "var=value shift" not poss!
shift ;;
esac
# From: werner...@ubs.com (Werner Burri)
# zsh 2.5.x/3.0.x error: "whichshell: read-only variable: LINENO [60]"
IFS=' ' LINENO= RANDOM= a=$[1] retval=0
a=2 a=$[3] wait 2>/dev/null
case $a:$LINENO:$RANDOM in
1*) # use BASH_VERSION?
if (: ${!a}) 2>/dev/null
then SHTYPE=BASH_2 # bash 2.00 (IRIX 5.x)
else SHTYPE=BASH_1 # bash 1.14.7(2) (IRIX 5.x)
# From: werner...@ubs.com (Werner Burri)
[ "${ZSH_VERSION:-${VERSION#zsh }}" > 2.5 ] &&
SHTYPE=ZSH_${ZSH_VERSION:-${VERSION#zsh }}
fi ;;
'$[3]::'*)
SHTYPE=KSH_1986 ;; # ksh 6/3/86
$\[[13]]:1:[0-9]*)
# some ksh88s are modified to apparently conform to POSIX 1003.2
if (: ${.sh.version}) 2>/dev/null
then SHTYPE=KSH_1993 # ksh M-12/28/93e (SunOS 4.x, IRIX 5.x)
else SHTYPE=KSH_1988 # ksh 11/16/88f (AIX 4.x, OSF/1 3.x)
#SHTYPE=KSH_1988POSIX # ksh 11/16/88f (AIX 4.x, OSF/1 3.x)
fi ;;
'$[3]::')
SHTYPE=SH_1994 ;; # sh SVR4 (UnixWare)
2::) case $SHTYPE in
SH_OLD) ;;
*) if (_(){ :;}) 2>/dev/null
then SHTYPE=SH_1983 # sh SVR3 Unix
else SHTYPE=SH_1977 # sh SVR2 Unix
fi ;;
esac ;;
#3*) SHTYPE=ZSH_ ;; # zsh 2.3.1 (IRIX 5.x)
*) retval=1 SHTYPE=`
IFS=/
set -- ${SHELL:-UNKNOWN}
until test \$# -eq 1
do shift
done
echo "\$1"
` ;;
esac
eval $shcmd$SHTYPE
exit $retval

#03 CSHELL FAMILY
CSH:
unset path
if ("X$a" == X) then
set shcmd = 'echo '
else
set argv = ($a) shcmd = "source $1."
shift
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: # tcsh 1.2 1993/07/15 (IRIX 5.x)
set SHTYPE = TCSH
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
--

#04 EMBEDDED MANPAGE FOR "src2man"
#++
NAME
whichshell - determine which shell this script runs under

SYNOPSIS
whichshell [script [script-parameter(s)]]

DESCRIPTION
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)>.

Whichshell knows about bash 1.x/2.x, csh, ksh86/88/93, V7/SVR2 sh,
SVR3 sh, POSIX sh, tcsh, #XXXand zsh.

EXAMPLE
csh -f whichshell init p1 p2 p3
sh -f whichshell init p1 p2 p3
ksh -f whichshell init p1 p2 p3

It is assumed that files "init.{CSH,KSH_1988,SH}" exist having
valid csh, ksh[88], and sh code, respectively. Or another
technique may be to create links "init.KSH_1988" and "init.KSH_1993"
that point to "init.SH", and a link "init.TCSH" to "init.CSH".

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 (barring an explicit "exit" command therein.)

CAVEATS
This script cannot be sourced; it must be executed within a
subshell.

Bash 1.x will attempt to source an $ENV script meant for ksh or
other shells.

Different sources document the release year of the various shells
distributed with the canonical releases of Unix; however, whichshell
only stipulates that such numbers be formally increasing for each
major family of shell.

To be truly robust for very ancient sh's: eliminate all comments
but the first.

Until weirdnik zsh can decide on how to act whether interactive
or not, whichshell cannot be expected to either.

BUGS
Positional parameter(s) cannot have embedded whitespace or
special characters.

#--

-Brian

PH

unread,
Nov 16, 1999, 3:00:00 AM11/16/99
to
Thanks Dan, nice trick!

-Paul


Dan Mercer

unread,
Nov 16, 1999, 3:00:00 AM11/16/99
to
In article <s30uv6...@corp.supernews.com>,

brian hiles <b...@rainey.blueneptune.com> writes:
> Dan Mercer <dame...@mmm.com> wrote:
>> In article <38300E2A...@siep.shell.com>,
>> PH <p.p.h.v...@siep.shell.com> writes:
>> check_version() { typeset version=ksh93; }
>> version=ksh88
>> check_version
>
> To determine the version of a shell throughto existance of
> non-existance of a bug is not the most robust way to do this.
>

This is not a bug - it is a difference in the way posix style
functions are executed under ksh88 and ksh93. Which is exactly
the kind of difference you look for in your script.

0 new messages