KSH Description (1200+ Lines)

Bill Wisner bdw at chinet.UUCP
Fri Feb 14 12:39:12 AEST 1986


We have ksh on chinet, and this document has been floating around for a
while. It is a description/abstract/explanation of ksh, the Korn Shell.
It does NOT include information on licensing, etc, but I may be able to
post that within a few days (after talking to root)..



--cut here---------------------and here--------------------here, too--
       1.  Introduction

       Over the	past two or three years	several	 papers	 have  been
       written	describing  new	 command  interpreters for the UNIX
       system.	These papers can be divided  into  two	categories:
       Those  that improve the shell as	a programming language,	and
       those that improve the shell as a command interpreter.  Most
       of the papers fall into the latter category.  In	particular,
       vicmd[3]	preserves the  friendly	 environment  of  vi  (from
       which  this  memo  was  entered),  and  adds  a facility	for
       convenient command entry.  An emacs oriented shell has  also
       been written by Veach[4].   The	2dsh[5]	 shell	allows	the
       setup  of  more	complicated networks of	processes than just
       pipelines.  The	See-shell[6]  proposes	a  Small-Talk  like
       interface[7] suitable for bit-mapped terminals such  as	the
       BLIT[8] and the Apollo[9].  Perhaps  the	 most  widely  used
       shell, other than the Bourne shell, is Csh, which runs under
       the Berkeley UNIX operating system.  Csh	has many attractive
       command	interpreter  features  not  currently in the Bourne
       shell; most notably, job	control, history,  arithmetic,	and
       command	name  aliasing.	  On  the  other  hand,	many people
       (including this author),	think  that  the  Bourne  shell	 is
       superior	 as  a programming language.  The history mechanism
       of Csh has recently been	added as a  local  modification	 to
       the Bourne shell	by J. L. Steffen[10].

       The use of the shell as	a  programming	language  has  been
       described by Dolotta and	Mashey[11] and	has  been  used	 by
       many  people  here  at  Bell   Laboratories.    Kolettis[12]
       presented  extensions to	the Bourne shell to provide message
       passing facilities and other inter-process communication	and
       synchronization features.  The  Form  shell[13]	added  form
       entry/edit capabilities to the Bourne shell.  A proposal	for
       a more programming language oriented shell has been proposed
       by Sturzenbecker[14].













				  - 2 -



       This memo describes Ksh,	aka the	Korn-shell.  This  memo	 is
       not  a  tutorial,  only	an  introduction.   Ksh	is a direct
       descendant  of  the  Form  shell	 with  most  of	 the   form
       entry/edit  features  removed  and  with	 many  new features
       added.  The primary focus of this work has been	to  provide
       an enhanced programming environment in addition to the major
       command entry features of  Csh.	 Improved  performance	has
       been  a	major  objective.   Many of the	additions have been
       provided	so that	 medium	 sized	programming  tasks  can	 be
       written	at  the	 shell	level without a	serious	performance
       penalty.	 A concerted effort has	been made to achieve System
       V Bourne	shell compatibility so that scripts written for	the
       Bourne shell can	run without  modification  with	 Ksh.	The
       description of features in this memo assumes that the reader
       is already familiar with	the Bourne shell.

       A version of Ksh	has been run on	several	machines  including
       a  VAX  11/780,	VAX  11/750, PDP-11/70,	PDP-11/23, IBM-370,
       AT&T 3B20, and Apollo Domain.  It has been  run	on  top	 of
       several	versions  of  the  UNIX	 operating system including
       System III, System V, BSD 4.1, BSD  4.1c,  4.2,	and  Apollo
       UNIX.   The  shell is in	use in several centers at AT&T Bell
       Laboratories, and has been installed as	/bin/sh	 on   VAXEN
       running	System	V, BSD 4.1., BSD 4.2 and on a 3B-20 running
       System V.


       2.  Shell Variables

       The ability  to	define	and  use  variables  to	 store	and
       retrieve	 values	is an important	feature	in most	programming
       languages.  Ksh has variables with identifiers  that  follow
       the  same  rules	 as  the Bourne	shell.	Since all variables
       have string representations, there is no	need to	specify	the
       type  of	 each variable in the shell.  In Ksh, each variable
       can have	one or more attributes that  control  the  internal
       representation  of  the	variable,  the	way the	variable is
       printed,	and its	access or scope.  Two  of  the	attributes,
       readonly	and export, are	available in the Bourne	shell.	The
       typeset	built-in  command  of  Ksh  assigns  attributes	 to
       variables.   The	 list  of  attributes appears in the manual
       page.  The unset	built-in of  the  Ksh  removes	values	and
       attributes of parameters.

       Whenever	a value	is assigned to a  variable,  the  value	 is
       transformed  according  to  the	attributes of the variable.
       Changing	the attribute of a variable can	change	its  value.
       There are three attributes for field justification, as might
       be needed for  formatting  a  report.   For  each  of  these
       attributes,  the	 first	time  an  assignment is	made to	the
       variable	its size is  remembered.   Each	 assignment  causes











				  - 3 -



       justification   of   the	 field,	 truncating  if	 necessary.
       Assignment to fixed sized variables provides a simple way to
       generate	 a  substring  consisting  of  a  fixed	 number	 of
       characters from the beginning or	end of a string.

       The attributes -u and -l, are used for upper case and  lower
       case  formatting	 respectively.	 Since it makes	no sense to
       have both attributes on simultaneously, turning on either of
       these  attributes turns the other off.  The following script
       provides	an example of  the  use	 of  shell  variables  with
       attributes.    This  script  reads  a  file  of	lines  each
       consisting of five fields separated by :	and prints fields 4
       and  2  in  upper  case in columns 1-15,	left justified,	and
       columns 20-25 right-justified respectively.

	    typeset -Lu	f4=123456789012345    #	15 character left justified
	    typeset -Ru	f2=123456	      #	6 character right justified
	    IFS=:
	    set	-f			      #	skip file name generation
	    while   read -r f1 f2 f3 f4	f5    #	read line, split into fields
	    do	    print -r "$f4    $f2"     #	print fields 4 and 2
	    done


       The  integer  attribute,	 -i,  causes  the  variable  to	 be
       internally  represented as an integer.  The first assignment
       to an integer  variable	determines  the	 output	 base  (see
       below).	 This  base  will  be used whenever the	variable is
       printed.	 Assignment to integer typed  variables	 result	 in
       arithmetic evaluation, as described below, of the right hand
       side.

       Ksh allows one-dimensional  arrays  in  addition	 to  simple
       variables.  Any variable	can become an array by referring to
       it with a subscript.  All elements  of  an  array  need	not
       exist.	Subscripts  for	 arrays	must evaluate to an integer
       between 0 and 127, otherwise an error  results.	 Evaluation
       of  subscripts is described in the next section.	 Attributes
       apply to	the whole array.

       Assignments to array variables are  made	 with  the  typeset
       built-in.  Referencing of subscripted variables requires	the
       character $, but	 also  requires	 braces	 around	 the  array
       element name.  The braces are needed to avoid conflicts with
       the file	name generation	mechanism.  The	form of	 any  array
       element reference is:
			   ${name[subscript]}.
       A subscript value of * or @ can	be  used  to  generate	all
       elements	 of  an	 array,	 as  they are used for expansion of
       positional parameters.












				  - 4 -



       A  few  additional  operations  are   available	 on   shell
       variables.   ${#name} will be then length in bytes of $name.
       For an  array  variable	${#name[*]}  gives  the	 number	 of
       elements	in the array.

       There are two parameter	substitution  modifiers	 that  have
       been  added  to	strip  off  leading and	trailing substrings
       during parameter	substitution.  The modifier  #	strips	off
       from  the left and the modifier % strips	off from the right.
       For example, if the shell variable i has	value file.c,  then
       the  expression	${i%.c}	 has  value  file.   The  substring
       built-in	has been  added	 to  Ksh  to  enable  the  user	 to
       generate	a substring of a given string.	The built-in allows
       the user	to specify an expression to  be	 deleted  from	the
       left  and right ends of the string.  The	resulting substring
       is printed out.	Command	substitution can be used to  assign
       the output of substring to a shell variable.


       3.  Arithmetic Evaluation

       The built-in  command,  let,  provides  the  ability  to	 do
       integer	 arithmetic.	All   arithmetic   evaluations	are
       performed using long arithmetic.	 Arithmetic  constants	are
       written as
			       base#number
       where base is a decimal integer between two  and	 thirty-six
       and  number is any positive integer.  Base ten is used if no
       base is specified.

       Arithmetic expressions are made from  constants,	 variables,
       and  one	 or  more  of  the fourteen operators listed in	the
       manual  page.   Operators  are	evaluated   in	 order	 of
       precedence.   Parentheses  may  be  used	 for  grouping.	  A
       variable	does not have to have an integer  attribute  to	 be
       used  within  an	 arithmetic  expression.   The	name of	the
       variable	is replaced  by	 its  value  within  an	 arithmetic
       expression.  The	statement
				let x=x+1
       can be used to increment	a variable x.  Note that  there	 is
       no  space  before  or  after the	operators + and	=.  This is
       because each argument to	let is an expression  to  evaluate.
       The  last  expression  determines the value returned by let.
       If the last expression evaluates	to a  non-zero	value,	the
       let returns true.  Otherwise, let returns false.

       Note that many of  the  arithmetic  operators  have  special
       meaning	to the shell and must be quoted.  Since	this can be
       burdensome,  an	alternate  form	 of  arithmetic	 evaluation
       syntax  has been	provided.  For any command that	begins with
       ((, all the characters until the	matching )) are	treated	 as











				  - 5 -



       a  quoted  arithmetic  expression.   The	 double	parentheses
       usually avoids incompatibility with the Bourne  shell's	use
       of parentheses for grouping a set of commands to	be run in a
       sub-shell.   Expressions	 inside	 double	  parentheses	can
       contain blanks and special characters without quoting.  More
       precisely,
				(( ... ))
       is equivalent to
			       let " ... "

       The following  script  prints  the  first  n  lines  of	its
       standard	input onto its standard	output,	where n	is supplied
       as an argument or is 20 if omitted.

	    typeset -i n=${1-20}		    # set n
	    while   read -r line && (( (n=n-1)>=0 ))# at most n	lines
	    do	    print -r - "$line"
	    done



       4.  Functions and Command Aliasing

       Two new mechanisms have been provided for  creating  pseudo-
       commands,  i. e., things	that look like commands, but do	not
       always create a process.	  The  first  technique	 is  called
       command name aliasing.

       As a command is being read,  the	 command  name	is  checked
       against	a list of alias	names.	If it is found,	the name is
       replaced	by the text associated	with  the  alias  and  then
       rescanned.   The	text of	an alias is not	checked	for aliases
       so recursive definitions	are not	allowed.

       Aliases are defined with	the alias built-in.  The form of an
       alias command is:
			     alias name=value
       Except for the first character, which must be printable,	the
       alias  name  must  be  a	 valid identifier.  The	replacement
       text, value, can	contain	any valid shell	 script,  including
       metacharacters  such  as	 pipe  symbols and i/o-redirection.
       Aliases can be used to redefine built-in	 commands  so  that
       the alias
			    alias test=./test
       can be used  to	look  for  test	 in  your  current  working
       directory  rather  than	using  the  built-in  test command.
       Keywords	 such  as  for	and  while  cannot  be	changed	 by
       aliasing.  The command alias, without arguments,	generates a
       list  of	 aliases  and  corresponding  texts.   The  unalias
       command removes the name	and text of an alias.












				  - 6 -



       Aliases are used	to save	typing and to  improve	readability
       of  scripts.   For example, the alias alias integer='typeset
       -i' allows integer the variables	i and j	to be declared	and
       initialized with	the command integer i=0	j=1.

       One frequent use	of aliases is to alias a  command  name	 to
       the full	path-name of the program.  This	eliminates the path
       search but requires knowledge of	where that program will	 be
       stored.	 To  reduce  the  amount of path searching, tracked
       aliases have been introduced.  A	tracked	alias is not  given
       a  value.   Its value is	defined	at the first reference by a
       path-search as the full path-name equivalent  of	 the  name,
       and  remains  defined  until  the  PATH variable	is changed.
       Programs	found in directories that do not begin with /  that
       occur  earlier  in  the	path-search  than  the value of	the
       tracked alias, take precedence over tracked aliases.

       Tracked aliases provide an alternative to  the  Csh  command
       hashing	facility.  Tracked  aliases do not require time	for
       initialization and allow	for new	commands to  be	 introduced
       without	the  need  for	re-hashing.  An	option to the shell
       allows all command names	 that  are  valid  alias  names	 to
       become tracked aliases.

       Functions are  more  general  than  aliases  but	 also  more
       costly.	Functions definitions are of the form

	    function name
	    {
	    any	shell script
	    }

       The function is	invoked	 by  writing  name  and	 optionally
       following  it  with  arguments.	 Positional  parameters	are
       saved before each function call and restored when completed.
       Functions  are executed in the current shell environment	and
       can share named variables with  the  calling  program.	The
       return  built-in	can be used to cause the function to return
       to the statement	following the point of invocation.

       By default, variables are  inherited  by	 the  function	and
       shared	by   the  calling  program.   However,	environment
       substitutions preceding the function call apply only to	the
       scope  of  the  function	call.  Also, variables defined with
       the typeset, built-in command are local to the function that
       they are	declared in.  Thus, for	the function defined

	    function  name
	    {
		 typeset -i x=10
		 let z=x+y











				  - 7 -



		 print $z
	    }

       invoked as y=13 name, x	and  y	are  local  variables  with
       respect to the function name while z is global.

       Alias and function names	are never directly  carried  across
       separate	 invocations of	Ksh, but can be	passed down to sub-
       shells.	The -x flag is used with alias to carry	aliases	 to
       sub-shells while	the -fx	flags of typeset are used to do	the
       same for	functions.

       Several of the UNIX commands can	be aliased  to	Ksh  built-
       ins.   Some  of	these  are  automatically set each time	the
       shell is	invoked.  In addition, about twenty frequently used
       UNIX  commands  are  set	 as tracked aliases.  Each user	can
       create a	 file  for  aliases  and  functions.   Aliases	and
       functions that are to be	available for all shell	invocations
       should be put into the Ksh startup  file.   By  setting	and
       exporting the environment variable, ENV,	to the name of this
       file, the aliases and functions will be	defined	 each  time
       Ksh  is	invoked.   The	value of the ENV variable undergoes
       macro and command substitution prior to its use.	 Since	the
       ENV file	is not invoked automatically for a log in shell, it
       is usually necessary to include the line	eval . $ENV in your
       .profile	file.


       5.  Input and Output

       An extended I/O capability has been added to enhance the	use
       of  the	shell  as a programming	language.  The Bourne shell
       has a built-in read for reading lines from  file	 descriptor
       0,  but	does  not have any internal output mechanism.  As a
       result, the echo(1) command has been used to produce  output
       for  a  shell  procedure.   This	 is  inefficient  and  also
       restrictive.  For example, there	is no way to read in a line
       from  a terminal	and to echo the	line exactly as	is.  In	the
       Bourne shell, the read built-in cannot be used to read lines
       that  end  in  `\',  and	the echo command will treat certain
       sequences as control sequences.	In addition,  there  is	 no
       way to have more	than one file open at any time for reading.

       Ksh has options on the read  command  to	 specify  the  file
       descriptor  for the input.  The exec built-in can be used to
       open and	close file streams.  The -r option allows a `\'	 at
       the  end	 of  an	 input	line  to  be  treated  as a regular
       character rather	than the line continuation character.	The
       first  argument	of  the	read command can be followed by	a ?
       and a prompt to produce a prompt	at the terminal	before	the
       read.   If  the input is	not from a terminal device then	the











				  - 8 -



       prompt is not issued.

       The Ksh built-in, print,	is used	to output characters to	the
       terminal	or to a	file.  Again, it is possible to	specify	the
       file  descriptor	 number	 as  an	 option	 to  the   command.
       Ordinarily,  the	arguments to this command are processed	the
       same as for echo(1).  However, the -r flag can  be  used	 to
       output  the  arguments  without any special meaning.  The -n
       flag can	be used	here to	suppress the trailing new-line that
       is ordinarily appended.

       To improve performance of existing shell	programs, an  alias
       for  echo  is  defined by the shell when	it is invoked.	For
       the AT&T-UNIX version, the alias	is
			  alias	echo='print -',
       where the - signifies that there	are no more options,  while
       for the Berkeley	UNIX version
			  alias	echo='print -R',
       where the -R option allows only the -n flag to be recognized
       as the next argument, gives the desired result.

       The shell is frequently used as a programming  language	for
       interactive  dialogues.	The select statement has been added
       to the language to make it easier to present menu  selection
       alternatives  to	 the user and evaluate the reply.  The list
       of alternatives is numbered and	put  in	 columns.   A  user
       settable	 prompt,  PS3,	is  issued  and	 if the	answer is a
       number corresponding to one of the alternatives,	the  select
       loop  variable is set to	this value.  In	any case, the REPLY
       variable	is used	to store the user entered reply.


       6.  Command Re-entry

       An interactive shell  saves  the	 commands  you	type  at  a
       terminal	 in a file.  If	the variable HISTFILE is set to	the
       name of a file to which the user	has write access, then	the
       commands	 are  stored  in  this history file.  Otherwise	the
       file $HOME/.history is checked for write	access and if  this
       fails  an  unnamed  file	 is used to hold the history lines.
       This file is truncated if this is a top	level  shell.	The
       number  of commands accessible to the user, is determined by
       the value of the	HISTSIZE variable at the time the shell	 is
       invoked.	 The default value is 64.  A command may consist of
       one or more lines since a compound command is considered	one
       command.	  If  the character !  is placed within	the primary
       prompt string, then it is replaced  by  the  command  number
       each  time the prompt is	given.	Whenever the file is named,
       all shells which	use this file  share  access  to  the  same
       history.












				  - 9 -



       A built-in command fc (fix command) is used to  list  and/or
       edit any	of these saved commands.  The command can always be
       specified with a	range of one or	more commands.	 The  range
       can  be	specified by giving the	command	number,	relative or
       absolute, or by giving the first	character or characters	 of
       the  command.   The  option -l is used to specify listing of
       previous	commands.  When	given without specifying the range,
       the  last  16  commands	are  listed,  each  preceded by	the
       command number.

       If the listing option is	not selected,  then  the  range	 of
       commands	 specified,  or	 the  last  command  if	no range is
       given, is passed	to  an	editor	program	 before	 being	re-
       executed	 by  Ksh.   The	 editor	to be used may be specified
       with the	option -e and following	it with	 the  editor  name.
       If  this	 option	 is  not  specified, the value of the shell
       variable	FCEDIT is used as the name of the editor, providing
       that  this variable has non-null	value.	If this	variable is
       not set,	or  is	null,  and  the	 -e  option  has  not  been
       selected,  then	/bin/ed	 is  used.   When  editing has been
       complete, the edited text automatically	becomes	 the  input
       for Ksh.	 As this text is read by Ksh, it is echoed onto	the
       terminal.

       An editor name of - is used to bypass the editing  and  just
       re-execute  the command.	 In this case only a single command
       can be specified	as the range and an  optional  argument	 of
       the form	old=new	may be added which requests a simple string
       substitution prior to evaluation.  A convenient alias,
			    alias r='fc	-e -'
       has been	pre-defined so that the	single key-stroke r can	 be
       used  to	 re-execute the	previous command and the key-stroke
       sequence, r abc=def c can be used  to  re-execute  the  last
       command	that  starts  with  the	 letter	 c  with  the first
       occurrence of the string	abc replaced with the  string  def.
       Typing  r  c  >	file  re-executes  the	most recent command
       starting	with the letter	c, with	standard output	 redirected
       to file.


       7.  In-line editing

       Lines typed from	a terminal  frequently	need  changes  made
       before entering them.  With the Bourne shell the	only method
       to fix up commands is by	backspacing or	killing	 the  whole
       line.   Ksh offers options that allow the user to edit parts
       of the current command line before submitting  the  command.
       The in-line edit	options	make the command line into a single
       line screen edit	window.	 When the command  is  longer  than
       the  width of the terminal, only	a portion of the command is
       visible.	 Moving	within the line	 automatically	makes  that











				  - 10 -



       portion	visible.   Editing  can	be performed on	this window
       until the return	key is pressed.	  The  editing	modes  have
       commands	 that  access  the  history  file in which previous
       commands	are saved.  A user can copy any	of the most  recent
       HISTSIZE	commands from this file	into the input edit window.
       You can locate commands by searching or by position.

       The in-line editing options do not use the termcap database.
       They  work  on  most  standard terminals.  They only require
       that the	backspace character moves the cursor left  and	the
       space  character	 overwrites  the  current  character on	the
       screen.

       There is	a choice of editor options.  The emacs,	 gmacs,	 or
       vi option is selected by	turning	on the corresponding option
       of the set command.  If the value of the	 EDITOR	 or  VISUAL
       ends  any  of  these  suffixes  the corresponding options is
       turned on.  A large subset of each of each of these  editors
       features	  are	available  within  the	shell.	 Additional
       functions, such as file	name  completion,  have	 also  been
       added.

       The code	for the	emacs and gmacs	editing	option was supplied
       by  Mike	 Veach.	  In  the  emacs  or  gmacs  mode  the user
       positions the cursor to the  point  needing  correction	and
       inserts,	 deletes,  or  replaces	 characters as needed.	The
       only difference between these two modes is  the	meaning	 of
       the  command ^T.	 Control keys and escape sequences are used
       for cursor positioning and control functions.  The available
       editing functions are listed in the manual page.

       The code	for the	vi  editing  option  was  supplied  by	Pat
       Sullivan.   The	vi  editing  mode starts in insert mode	and
       enters control mode when	the  user  types  ESC(	033).	The
       return	key,   which   submits	 the  current  command	for
       processing, can be entered from either mode.  The cursor	can
       be  anywhere  on	 the  line.   A	 subset	of commonly used vi
       commands	are available.	The k and j command  that  normally
       move  up	 and down by one line, move up and down	one command
       in the history file, copying the	command	at into	 the  input
       edit  window.   For  reasons  of	efficiency, the	terminal is
       kept in canonical mode until  an	 ESC  is  typed.   On  some
       terminals,  and	on  earlier  versions of the UNIX operating
       system, this doesn't work correctly.  The  viraw	 option	 of
       the  set	command, which always uses raw or cbreak mode, must
       be used in this case.
















				  - 11 -



       8.  Job Control

       The job control mechanism is almost identical to	the version
       found  in Csh of	the Berkeley UNIX operating system, version
       4.1.  The job control feature allows the	user  to  stop	and
       restart	programs,  and	to  move  programs  to and from	the
       foreground and the background.  It will only work on systems
       that  provide  support  for  these  features.  However, even
       systems without job control have	a monitor option which when
       enabled	will  report  the  progress  of	background jobs	and
       enable the user to kill jobs by job number or job name.

       An interactive shell associates a  job  with  each  pipeline
       typed  in from the terminal and assigns them a small integer
       number  called  the  job	 number.   If  the   job   is	run
       asynchronously,	the  job number	is printed at the terminal.
       At any given time, only one job owns the	 terminal,  i.	e.,
       keyboard	 signals are only sent to the processes	in one job.
       When Ksh	creates	a foreground job, it gives it ownership	 of
       the  terminal.  If you are running a job	and wish to stop it
       you hit the key ^Z (control-Z) which sends a STOP signal	 to
       all  processes  in  the	current	 job.	The  shell receives
       notification that the processes have stopped and	takes  back
       control of the terminal.

       There are commands to continue programs	in  the	 foreground
       and  background.	  There	 are several ways to refer to jobs.
       The character % introduces a job	name.	You  can  refer	 to
       jobs by name or number as described in the manual page.	The
       built-in	command	bg allows you to  continue  a  job  in	the
       background,  while  the	built-in  command  fg allows you to
       continue	a job in the foreground	even though  you  may  have
       started it in the background.

       A job being run in the background will stop if it  tries	 to
       read  from  the	terminal.   It	is  also  possible  to stop
       background jobs that try	to write on the	terminal by setting
       the terminal options appropriately.

       There is	a built-in command jobs	that lists  the	 status	 of
       all running and stopped jobs.  In addition, you are notified
       of the change of	state of any background	 jobs  just  before
       each prompt.  When you try to leave the shell while jobs	are
       stopped or running, you will receive a message from Ksh.	 If
       you  ignore this	message	and try	to leave again,	all stopped
       processes will be terminated.

       A built-in version of kill makes	 it  possible  to  use	job
       numbers	as targets for signals.	 Signals can be	selected by
       number or name.	The name of the	signal is the name found in
       the  include  file /usr/include/signal.h	with the prefix	SIG











				  - 12 -



       removed.	 The list of valid signal names	 can  be  generated
       with the	-l flag	of kill.


       9.  Miscellaneous

       Ksh has several additional features to enhance functionality
       and performance.	 This section lists most of these features.

       9.1  Tilde substitution

       The character 8 at the  beginning  of  a	 word  has  special
       meaning	to  Ksh.   If  the characters after the	8 up to	a /
       match a user login name in the /etc/passwd file,9then the  8
       and  the	 name  are replaced by that user's login directory.
       If no match is found, the original word is unchanged.   A  8
       by  itself,  or in front	of a /,	is replaced by the value of
       the HOME	parameter.  A 8	followed by a +	or - is	replaced by
       the  value  of  the  parameter  PWD and OLDPWD respectively.
       Tilde substitution takes	place when the script is read,	not
       while it	is executed.

       9.2  Built-in I/O Redirection

       All built-in commands can be redirected.

       9.3  Added options

       Several options have been added to the shell and	all options
       have  names  that  can be used in place of flags	for setting
       and resetting options.  The command set	-o  will  list	the
       current option settings.

       The option, -f or  noglob  is  used  to	disable	 file  name
       generation.  It can be applied at invocation or as an option
       to the set command.

       The option ignoreeof can	be used	in  a  top-level  shell	 to
       prevent	^D from	logging	you out.  You must type	exit to	log
       out.

       The -h or trackall option will cause all	commands whose name
       is a valid alias	name to	become a tracked alias.

       The job monitor option will cause a  report  to	be  printed
       when  each  background  job  completes.	It is automatically
       enabled for systems that	have job control.

       If the bgnice option is set, background jobs are	 run  at  a
       lower priority.












				  - 13 -



       9.4  Previous Directory

       Ksh remembers your last directory in  the  variable  OLDPWD.
       The  cd	built-in  can be given with argument - to return to
       the previous directory.	Note that cd - done  twice  returns
       you  to	the  starting  directory,  not	the second previous
       directory.  A directory stack can be implemented	with  shell
       internals  by  using an array and writing shell functions to
       push and	pop directories	from the stack.

       9.5  Additional Variables and Parameters

       Several new parameters have special  meaning  to	 Ksh.	The
       variable	 PWD  is used to hold the current working directory
       of the shell.  The command, pwd,	is aliased to print -  $PWD
       for  better  response.	The variable OLDPWD is used to hold
       the previous working directory of the shell.

       The variable FCEDIT is used by  the  fc	built-in  described
       above.	The  variables	VISUAL	and  EDITOR  are  used	for
       determining the edit modes as described above.

       The variable ENV	is used	to  define  the	 startup  file	for
       non-login Ksh invocations.

       The variables HISTSIZE and HISTFILE  control  the  size	and
       location	 of  the  file	containing  commands  entered  at a
       terminal.

       The parameter MAILPATH is a colon ( : )	separated  list	 of
       file  names to be checked for changes periodically. The user
       is notified before the next prompt.  Each of  the  names	 in
       this  list  can be followed by a	?  and a prompt	to be given
       when a change has been detected in  the	file.	The  prompt
       will  be	 evaluated for macro and command substitution.	The
       parameter MAILCHECK is used to specify the minimal  interval
       in seconds before new mail is checked for.

       The variable RANDOM produces a random number each time it is
       referenced.   Assignment	 to this variable sets the seed	for
       the random number generator.

       The parameter PPID is used to generate the parent process id
       of the shell.

       The value of the	parameter _ is the  last  argument  of	the
       previous	command.

       The parameter TMOUT can be set to be the	number	of  seconds
       that the	shell will wait	for input before terminating.












				  - 14 -



       The COLS	variable can be	used to	adjust	the  width  of	the
       edit window for the in-line edit	modes.

       9.6  Modified variables

       The input field separator parameter, IFS,  has  meaning	for
       the read	built-in, for the set built-in,	and while expanding
       for and select lists.  In all other instances it	is ignored.

       9.7  Timing Commands

       A keyword time has been added to	replace	the  time  command.
       Any  function,  command	or pipeline can	be preceded by this
       keyword to obtain information about the	elapsed,  user	and
       system  times.	Since  I/O redirection bind to the command,
       not to time, parenthesis	should	be  used  to  redirect	the
       timing	information  which  is	normally  printed  on  file
       descriptor 2.

       9.8  Command Substitution

       The special command substitution	of the form `cat file`	can
       be replaced by `< file`,	which is faster	because	no separate
       process is created.

       9.9  Whence

       The addition of aliases,	functions, and more  built-ins	has
       made  it	 substantially	more difficult to know what a given
       command word really means.  A built-in command, whence  when
       used  with  the	-v  option has been provided to	answer this
       question.  A line is printed for	 each  argument	 to  whence
       telling	what  would  happen if this argument were used as a
       command name.  It reports on keywords,  aliases,	 built-ins,
       and  functions.	 If  the  command  is none of the above, it
       follows the path	search rules and prints	the full path-name,
       if any, otherwise it prints an error message.

       9.10  Additional	test operators

       The operators -ot  and  -nt  can	 be  used  to  compare	the
       modification  times  of	two  files  to see which is file is
       older than or newer than	the other.   The  operator  -ef	 is
       used  to	 see  if  two files have the same device and i-node
       number, i. e., a	link to	the same file.

















				  - 15 -



       9.11  Shell Accounting

       There is	a compile time option to the shell to  generate	 an
       accounting  message  for	 each  shell  script.	The changes
       needed to provide this feature were supplied by Foregger[15]
       and have	been adopted as	described in his memo.

       9.12  Coded in Standard C

       The Bourne shell	is coded in an ALGOL-68	like dialect of	 C.
       Ksh is coded in standard	C.

       9.13  No	special	meaning	for ^

       The Bourne shell	uses ^ as an archaic synonym for |.  The  ^
       is not a	special	character to Ksh.


       10.  Example

       An example of a Ksh script  is  included	 in  the  Appendix.
       This  one  page	program	 is  a	variant	of the UNIX grep(1)
       program.	 Pattern matching for this version  of	grep  means
       shell patterns consisting of ?, *, and [].

       The first half examines option flags.  Note that	all options
       except  -b  have	 been  implemented.   The  second half goes
       through each line of each file to look for a pattern match.

       This program is not intended to serve as	a  replacement	for
       grep;  just  as	an illustration	of the programming power of
       Ksh.  Note that no auxiliary processes are spawned  by  this
       script.	 It  was  written  and debugged	in under two hours.
       While performance is acceptable	for  small  programs,  this
       program	runs  at only one tenth	the speed of grep for large
       files.


       11.  Performance

       Ksh executes many scripts faster	than the  System  V  Bourne
       shell.	One  major  reason  is	that  many of the functions
       provided	by echo(1) and expr(1) are built-in.  The  time	 to
       execute	a  built-in  function  is  one	or  two	 orders	 of
       magnitude faster	than performing	a fork and execute  of	the
       shell.	Command	 substitution  of  built-ins  is  performed
       without creating	another	process,  and  often  without  even
       creating	a temporary file.

       Another reason for improved performance is that all  I/O	 is
       buffered.   Output  buffers  are	flushed	only when required.











				  - 16 -



       Several of the internal algorithms have been changed so that
       the  number  of	subroutine  calls  has	been  substantially
       reduced.	 Ksh uses hash tables for variables.  Scripts  that
       rely  heavily on	referencing variables execute faster.  More
       processing is performed while reading  the  script  so  that
       execution time is saved while running loops.

       Scripts that do little internal processing and  create  many
       processes  run  a little	slower because the time	to fork	Ksh
       is slower than for the Bourne shell.


       12.  Conclusion

       More than one thousand people have  tried  Ksh  and  use	 it
       regularly.   Ksh	 is  a	suitable replacement for the Bourne
       shell.  It offers new features, better performance,  and	 is
       essentially  upward  compatible with the	Bourne shell.  Many
       of the known bugs of the	Bourne shell have been eliminated.



       MH-59545-DGK-dgk		     D.	G. Korn

       Copy to
       Members of Center 5954
       Laboratory 4542 Supervision
       D. A. Lambeth
       N. J. Kolettis
       W. P. Weber
       E. G. Bradford
       J. L. Steffen
       S. L Arnold
       M. C. Sturzenbecker
       M. T. Veach
       J. Krist


























				  - 17 -



				References



	1. S. R. Bourne, An Introduction to the	UNIX Shell," BSTJ -
	   Vol.	57, No.	6 part 2, pages	1947-1972.

	2. W.  Joy,  An	 Introduction to the C Shell, University of
	   California, Berkeley, 1980.

	3. S. L. Arnold, Vicmd a Visual	Shell for Video	 Terminals,
	   TM-81-54533-12, 1981.

	4. J.  L.  Steffen  and	 M.  T.	 Veach,	 The  Edit  Shell -
	   Connecting Screen Editing with the History List,  USENIX
	   Association Toronto Proceedings, 1983.

	5. M.  J.  Rochkind,  2dsh  -  An  Experimental	 Shell	for
	   Connecting  Processes With Multiple Data Streams, TM-80-
	   9323-3.

	6. Wayne T. Wilner, See-Shell: a  Graphical  User-Interface
	   for UNIX Systems, Bell Laboratories internal	memorandum,
	   1982.

	7. D.  C.  Smith,  C.  Irby,  R.  Kimball, and B. Verplank,
	   Designing the Star User Interface,  BYTE,  April,  1982,
	   pp. 242-282.

	8. R. Pike, The	Blit Programmer's manual, Bell Labs, 1982.

	9. P. J. Leach,	P. H. Levine, B. P. Douros, J. A. Hamilton,
	   D.  L.  Nelson, and B. L. Stumfp, The Architecture of an
	   Integrated Local Network, IEEE Journal of Selected Areas
	   in  Communications,	Local  Area Networks Special Issue,
	   November 1983.

       10. J.  L.  Steffen,  An	Input History for the Bourne Shell,
	   TM-82-55426-3, 1982.

       11. T.  A.  Dolotta  and	 J. R. Mashey, Using the shell as a
	   Primary Programming	Tool,  Proc.  2nd.  Int.  Conf.	 on
	   Software Engineering, 1976, pages 169-176.

       12. N.  J. Kolettis.  Extended Shell - A	Potential Real Time
	   Interpreter,	TM-77-4145-01, 1977.

       13. D.  G. Korn and D. A. Lambeth, Form Shell, TM-80-9224-3,
	   1980.













				  - 18 -



       14. M. C. Sturzenbecker,	A New Command Language for UNIX	and
	   related systems, TM-82-45192-3.

       15. T. H. Foregger, Shell Accounting,  Case  40094-21,  July
	   1982.

























































			       ABSTRACT



     Ksh is a command language (shell) for the	UNIX*	operating
     system.   It  is  essentially  [1]patible	with the System	V
     version  of  the  Bourne  shell	 [2]has	 many  additional
     features, such as those found in Csh   , and executes faster
     than  either  of these shells.  This memo introduces many of
     the additional features and explains some of the reasons for
     the  better  performance.	This memo assumes that the reader
     is	already	familiar with the  Bourne  shell.   The	 Appendix
     contains  a  sample  script written in Ksh.  The manual page
     for the current version is	also included.


















_____________________________________________________________________







				 APPENDIX
	       #
	       #       SHELL VERSION OF	GREP
	       #
	       vflag= xflag= cflag= lflag= nflag=
	       set -f
	       while   ((1))		       # look for grep options
	       do      case    "$1" in
		       -v*)    vflag=1;;
		       -x*)    xflag=1;;
		       -c*)    cflag=1;;
		       -l*)    lflag=1;;
		       -n*)    nflag=1;;
		       -b*)    print 'b	option not supported';;
		       -e*)    shift;expr="$1";;
		       -f*)    shift;expr`< $`;;
		       -*)     print $0: 'unknown flag';exit 2;;
		       *)      if      test "$expr" = ''
			       then    expr="$1";shift
			       fi
			       test "$xflag" ||	expr="*${expr}*"
			       break;;
		       esac
		       shift		       # next argument
	       done
	       noprint=$vflag$cflag$lflag      # don't print if	these flags set
	       integer n=0 c=0 tc=0 nargs=$#   # initialize counters
	       for i in	"$@"		       # go thru the files
	       do      if      ((nargs<=1))
		       then    fname=''
		       else    fname="$i":
		       fi
		       test "$i"  &&  exec 0< $i       # open file if necessary
		       while   read -r line	       # read in a line
		       do      let n=n+1
			       case    "$line" in
			       $expr)		       # line matches pattern
				       if      test "$noprint" = ""
				       then    print -r	"$fname${nflag:+$n:}$line"
				       fi
				       let c=c+1 ;;
			       *)		       # not a match
				       if      test "$vflag"
				       then    print -r	"$fname${nflag:+$n:}$line"
				       fi;;
			       esac
		       done
		       if      test "$lflag" &&	((c))
		       then    print - $i
		       fi
		       let tc=tc+c n=0 c=0















	       done
	       test "$cflag" &&	print $tc      #  print	count if cflag is set
	       let tc			       #  set the exit value

-- 
Bill Wisner / The Computer Connection
UUCP:   ihnp4!chinet!bdw
CIS:    76474,1213
USNail: 6290 Highway 44
	Star, ID 83669

Witty Quote:		If you owned the universe, where would you put it?
Witty Disclaimer:	When I want your opinion, I'll give it to you.



More information about the Comp.unix mailing list