KSH-93 - Frequently Asked Questions

KSH-93

Frequently Asked Questions

This is a first draft of the ksh93 FAQ. HTML version coming soon. If there is anything you'd like to see on the FAQ, please send email to doc@kornshell.com.
I.	GENERAL QUESTIONS

Q1.	What is KornShell?
A1.	KornShell is a command and scripting language 
	that is a superset of the System V UNIX shell,
	aka, BourneShell (or 'sh').

Q2.	What is ksh?
A2.	ksh is the name of the program that implements the
	KornShell language.

Q3.	What is the history of ksh?
A3.	ksh was written by David Korn at Bell Telephone Laboratories.
	David Korn is currently at AT&T Laboratories.
	The first version of ksh was in 1983.  It was the first
	shell to have command line editing with both emacs
	and vi style interaction.  The 1986 version was the first
	to offer multibyte support.  The 1988 version of ksh
	is the version that was adopted by System V Release 4 UNIX
	and was a source document for the IEEE POSIX and ISO
	shell standards.  The 1993 version is a major rewrite
	of the 1988 version and focuses more on scripting.

Q4.	Where is the official description of the KornShell language?
A4.	The Bolsky and Korn book, "The KornShell Command and Programming
	Language", published by Prentice Hall, defines the 1988
	version.  The newer Bolsky and Korn book, "The New KornShell Command
	and Programming Language", also published by Prentice Hall,
	describes the 1993 version.

Q5.	What are the major new features of KornShell 1993?
A5.	The only major new interactive feature is key binding.
	Major new language features are floating point arithmetic,
	associative arrays, complete ANSI-C printf, name reference
	variables, new expansion operators, dynamic loading of
	built-in commands, active variables, and compound variables.
	Active and compound variables allow shell variables to
	behave like objects.  In addition, ksh93 has been written to be
	extensible with an C language API for programming extensions.

Q6.	Are any further releases of ksh planned?
A6.	Yes, we are in the process of planning for a newer version,
	ksh200X.  We are interested in suggestions for new features.
	Again, most of the focus will be on scripting and reusability.

Q7.	What new features are planned for ksh200X?
A7.	We are in the early stage of planning but the likely additions
	are namespaces, an inheritance mechanism for objects,
	and support for binary objects.  Support for multi-threading
	is also being considered.

Q8.	Is KornShell public domain?
A8.	Yes, the language description is public domain and
	can be reimplemented.  Some of the KornShell language
	features have been reimplemented in the GNU shell, bash
	and in pdksh, a public domain implementation.

Q9.	Is ksh public domain?
A9.	No, earlier versions were owned by both AT&T and Novell.
	The 1993 version is owned by both Lucent and AT&T.

Q10.	Is source code available?
A10.	Starting in March 2000, the ksh93 source is available
	as part of a larger collection of software called
	the ast-open software package which can be downloaded
	from the site http://www.research.att.com/sw/download.

Q11.	What are the licensing terms?
A11.	The exact license terms can be found in
	http://www.research.att.com/sw/license/ast-open.html

Q12.	Does the license allow binaries to be freely redistributed?
A12.	Yes, provided you make the license terms available to
	everyone you distribute binaries to.

Q13.	If I make changes to the code, do I have to make them public?
A13.	No, you do not have to make them public.  However, if you
	distribute the changes, you must allow us to be able
	to get these changes and distribute them along with the source.

Q14.	Why do most vendors ship ksh88, not ksh93?
A14.	Since ksh88 was included in System V release 4, most vendors
	have just included this version.  A separate license was
	required for ksh93 from either Lucent or AT&T.  We hope this
	situation changes with the release of ksh93 in open source form.

Q15.	Do you provide support for ksh?
A15.	No, we will try to fix any bugs we hear about in future
	releases, but we do not provide any official support.

Q16.	Is ksh supported commercially?
A16.	Global Technologies, Ltd, http://www.gtlinc.com, distributes
	and supports the "Common Operating Environment" which includes
	ksh all of the other ast-open tools.  They support it across
	a broad range of systems.  Software vendors that supply ksh with
	their systems typically support it for that system.

Q17.	What is pdksh and is it related to ksh or KornShell?
A17.	pdksh is a public domain version of a UNIX shell that is
	unrelated to ksh. It supports most of the 1988 
	KornShell language features and some of the 1993 features.
	Some KornShell scripts will not run with pdksh.

Q18.	How is the MKS Toolkit Kornshell related to  KornShell?
A18.	MKS Tookit Kornshell is a completely independent implementation
	that supports a subset of the 1988 KornShell language.

Q19.	What systems does ksh run on?
A19.	ksh has been written to be portable.  It has been ported
	to virtually every known UNIX system.  In addition it runs
	on non-UNIX systems such as IBM's MVS using OpenEdition, and
	Microsoft's Windows 9X, Windows NT and Windows 2000.
	ksh is part of the UWIN (Unix for Windows) software,
	http://www.research.att.com/sw/tools/uwin.

Q20.	Does ksh conform to the IEEE POSIX and ISO shell standard?
A20.	The 1993 version should conform to the 1992 standard.  At one
	point it had passed the test suite created by X/OPEN.

Q21.	Will KornShell 88 scripts run with KornShell 93?
A21.	In almost all cases, the answer is yes.  However,
	the IEEE POSIX and ISO standards required a few
	changes that could cause scripts to fail.  There is a
	separate document that lists all known incompatibilities.

Q22.	Can ksh run as /bin/sh?
A22.	We have installed ksh as /bin/sh on several systems without
	encountering any problems.  Our Linux systems use this
	instead of bash.
=====================================================

II.	INTERACTIVE SHELL QUESTIONS

Q1.	How do I get separate history files for shell?
A1.	ksh uses a shared history file for all shells that
	use the same history file name.  This means
	that commands entered in one window will be seen by
	shells in other windows.  To get separate windows,
	the HISTFILE variable needs to be set to different name
	before the first history command is created.

Q2.	Why does the screen width not function correctly when non-printing characters are in my prompt?
A2.	The shell computes the screen width by subtracting the width of
	the prompt from the screen width.  To account for non-printing
	characters, for example escape sequences that display in the title
	bar, follow these characters with a carriage return.  The shell
	starts recomputing the width after each carriage return.	

Q3.	What is the PS4 prompt and how is it used?
A3.	The PS4 prompt is evaluated and displayed before each line when
	running an execution trace.  If unset, a + and a <space> will
	be output before each line in the trace.  Putting '$LINENO'
	inside PS4 will cause the line number to be displayed.  Putting
	'$SECONDS' in the PS4 prompt will cause the elapsed time
	to be displayed before each line.  Note that single quotes
	are used to prevent the expansion from happening when PS4
	is defined.

Q4.	How is keybinding done?
A4.	ksh93 provides a KEYBD trap that gets executed whenever a key
	is entered from the keyboard.  Using this trap, and the associate
	array feature of ksh93, a keybind function can easily be written
	which will map any entered key sequence to another key sequence. 

Q5.	How do I get the arrow keys to work?
A5.	Starting with the 'h' point release, on most keyboards you
	do not have to do anything to get the arrow keys to work.
	However, if they do not generate standard escape sequences,
	then you will have to use a keybinding function to get them
	to work.

Q6.	Does ksh support file name completion?
A6.	Yes, it does.  The default key binding is <ESC><ESC>
	however, starting with the 'g' point release, <TAB> also works
	for completion.  Note, the vi users need to set -o viraw
	in order to get <TAB> completion to work.

Q7.	Does ksh support command completion?
A7.	If you perform completion on the first word of a command,
	ksh will do completion using aliases, functions, and commands.

Q8.	Is completion programmable?
A8.	Yes, using the key binding mechanism, you can script the behavior
	of any key and therefore cause the current contents of any
	line to be replaced by any other line.

Q9.	Is there any way to get the command-line editor to go to more than a single line?
A9.	In vi-mode, if you hit 'v' while in control mode, it will bring
	up a full screen version of vi on the current command.  The command
	will execute when you exit vi.

Q10.	Can I use the shell line editor on other commands?
A10.	The command ie, that comes along with shell, can be used
	to run line input oriented commands with command line editing.

Q11.	When I do echo 0, I am getting 267.  What does this mean?
A11.	ksh93 reports process that terminate with a signal as 256+signo.
	Earlier versions used 128+signo but this makes it impossible
	to distinguish from a command exit with that value.  If you run
		kill -l $?
	on this signal number, it will give the the name of the signal
	that caused this exit.

Q12.	When I type builtin, I notice that some of these are full pathnames.  What does this mean?
A12.	Builtins that are not bound to pathnames are always searched
	for before doing a path search.  Builtins that are bound
	to pathnames are only executed when the path search would
	bind to this pathname.

Q13.	What is a self generating man page?
A13.	A self generating man page is one that is generated by the
	option parser within that command using an extended version
	of the getopts function.  The man page can be generated in html,
	troff, or directly for the terminal.  Most builtin commands
	in the shell have self generating man pages so that you
	can run for example, kill --man or kill --html to get
	the description of kill to the screen or as an html file. 
	This same method can also be used for shell scripts.  Run
	getopts --man for more details.

Q14.	What is autoloading?
A14.	Autoloading was a method used in ksh88, and still permitted in ksh93
	to declare that a name corresponded to a function.  The function
	would be loaded and executed when first referenced.  This was
	necessary since FPATH was always searched after PATH with ksh88
	and therefore if you defined a function whose name was the same
	as that of a program on your path, the program on your path
	would have been executed.  With ksh93, when a pathname is
	encountered that is on PATH, but also is in FPATH, this directory
	is assumed to be a function directory.  Thus, you can have
	function directories searched before program directories so
	that autoloading is no longer needed.
=====================================================

III.	SHELL PROGRAMMING QUESTIONS

Q1.	What is the difference between * and @, for example,  and ?
A1.	When used outside of "", they are equivalent.  However, within
	double quotes, "$@" produces one argument for each positional
	parameter, and "$* produces a single argument.  Note that "$@"
	preserves arguments lists, whereas $* may not unless both
	word splitting and pathname expansion are disabled.

Q2.	Why do I need spaces around { and } but not around ( and )?
A2.	The characters ( and ) are shell metacharacters and are always
	treated specially.  For historical reasons, { and } were
	treated as reserved words and are only special as separate
	words at locations in which a command can begin.

Q3.	How do I get read to maintain the \ characters?
A3.	Use read -r instead.

Q4.	How can a write a ksh script that responds directly to each
	character so that you user just has to enter y, not y<return>?
A4.	There are two ways to do this.  The easiest is to use
		read -n1 x
	Alternatively, you could do
		function keytrap
		{
			.sh.edchar=${sh.edchar}$'\n'
		}
		trap keytrap KEYBD
	and then
		read x

Q5.	What is the purpose of $'...'?
A5.	The $'...' option was added to ksh93 to solve the problem
	of entering special characters in scripts.  It uses
	ANSI-C rules to translate the string between the '...'.
	It would have been cleaner to have all "..." strings handle
	ANSI-C escapes, but that would not be backwards compatible.

Q6.	What is the -n option used for?
A6.	You should always run ksh -n on each script you write.  The -n
	option will check for syntax errors on paths that might not
	even be checked when you run the script.  It also produces
	a number of warning messages.

Q7.	Why are both `...` and $(...) used for command substitution?
A7.	The `...` method has some rather strange quoting rules
	and does not nest easily.  $(...) was added to ksh88 to
	make command substitution easy to use.  `...` is provided
	for backwords compatibility only.

Q8.	How can I tell if all the commands of a pipeline have succeeded?
A8.	The pipefail option was added to the 'g' point release of ksh93.
	With pipefail set, a pipeline will fail if any element of the
	pipeline fails.  The exit status will be that of the first
	command that has failed.

Q9.	How do I connect to a socket from a shell script?
A9.	exec 3<> /dev/tcp/hostname/portnum 
	will open a tcp connection to portnum on hostname for
	reading and writing on file descriptor 3.  You can then
	use read and print statements with file descriptor 3,
	or redirection operators <&3 or >&3 to use these connections.

Q10.	What is the difference between [...] and [[...]]?
A10.	The [[...]] is processed as part of the shell grammar
	whereas [...] is processed like any other command.
	Operators and operands are detected when the command is
	read, not after expansions are performed.  The shell does not
	do word splitting or pathname generation inside  [[...]].
	This allows patterns to be specified for string matching
	purposes.

Q11.	How come [[ $foo == $bar ]] is true and [[ $bar == $foo ]] is false?
A11.	The == operator is not symmetrical.  It takes a string on the left
	and a pattern on the right.  However, if you double quote the right
	hand side, which removes the special meaning of pattern match
	characters, then this becomes a string comparison so that
	[[ "$foo" == "bar" ]] and [[ "$bar" == "$foo" ]] are equivalent.

Q12.	Why does have print since echo already exists is is widely used?
A12.	The behavior of echo varies from system to system.
	The POSIX standard does not define the behavior of echo when
	the first argument beings with a - or when any argument
	contains a \ character.  This makes echo pretty useless for
	use in portable scripts.

Q13.	What is $bar after,	echo foo | read bar?
A13.	The is foo.  ksh runs the last component of a pipeline
	in the current process.  Some shells run it as a subshell
	as if you had invoked it as  echo foo | (read bar).

Q14.	What is the difference between ((expr)) and $((expr))?
A14.	((expr)) is a command that evaluates an arithmetic expression.
	The exit status of this command is 0 if the expression
	evaluates to non-zero and is 1 if it evaluates to 0.
	0 is an string expansion that expands to a string
	representation of the value of this arithmetic expression.
	It can be used anywhere a variable substitution is premitted.

Q15.	What is the difference between $((x*y)) and $(($x*$y))?
A15.	In the first case the value of x and the value of y are multiplied
	together, and then their result is converted to a string.  In the
	second case variables $x, *, and $y are concatenated to form
	an arithmetic expression which is then evaluated.  This can
	yield different results, for example,
		x=2+3 y=4+5
		print $((x*y)) \$(($x*$y))
		45 19

Q16.	How do I handle filenames with spaces in them?
A16.	To be POSIX conforming, ksh has to do word splitting and
	pathname expansion the results of substitutions.  You can
	enclose variable substitutions in "..." to prevent both
	word splitting and pathname expansion.  Alternatively,
	you can disable word splitting by setting IFS='' and
	pathname generation with set -o noglob.

Q17.	What are active variables?
A17.	By default shell variables are passive.  They hold values
	given to them on assignment, and return values on reference.
	Active variables allow the assignment and reference (and
	other actions) be controlled by functions specific to that
	variable.  At the shell level, a 'get', 'set', or 'unset'
	shell function can be defined for any variable to make them
	active, so that the function  foo.set will be invoked whenever
	the variable foo is assigned a value.  At the C interface
	level, several functions can be stacked together for an
	active variable.

Q18.	What is the difference between function name and name()?
A18.	In ksh88 these were the same.  However, the POSIX standard
	choose foo() for functions and defined System V Release 2
	semantics to them so that there are no local variables
	and so that traps are not scoped.  ksh93 keeps the ksh88
	semantics for functions defined as function name, and
	has changed the name() semantics to match the POSIX
	semantics.  Clearly, function name is more useful.

Q19.	What are name reference variables and how are they used?
A19.	Reference variables are variables in which all references
	and assignments refer to the variable that they reference.
	For example,
		typeset -n name=$1
		name=value
	is equivalent to
		eval \$1='value'
	References are most useful for passing arguments such as
	arrays to functions.

Q20.	If i=1 and var1=some value, how do I print vartt to get its value?
A20.	Either use
		eval print \$var\$i
	or
		typeset -n x=var$i
		print $x

Q21.	How can I shift the elements of an array?
A21.	The shift special builtin-command only works for positional
	parameters.  However, noting that array subscripts start at 0,
	you can use
		set -A name "${name[@]:1}"
	to shift the array.

Q22.	Why are the braces required with array references, e. g.  ${x[1]}?
A22.	It would be nice to do $x[1], but the POSIX shell would expand $x
	and then search for the file pattern resulting by concatenating [1]. 
	ksh is POSIX compatible.

Q23.	How do I get the list of subscript names for an associative array?
A23.	The prefix operator ! in variable expansions can be used to
	get names.  To get the names of subscripts for an array, associative
	or indexed, use ${!var[@]}.

Q24.	How do I do global substitutions on the contents of shell variables?
A24.	Use // instead of / for global substitution, ${var//aa/bb} will
	expand to the value of  with each "aa" replace by "bb".

Q25.	How can I convert %XX values to ascii?
A25.	You can convert this to a sequence of ANSI C strings and then eval that
	string, for example suppose the variable 'foo' contains %XX strings,
	then	
		eval print -r -- "\$'${foo//'%'@(??)/'\x\1"'\$'"}'"
	will print out the string in ascii.

Q26.	I want to use exec to open a file.  How do I prevent the script from exiting if the exec fails?
A26.	If you run
		command exec ... || error ...
	then  error will be executed if the exec fails, but the script
	will not terminate.  The command builtin will prevent the shell
	from exiting when special built-ins fail.

Q27.	How do I execute a builtin inside a function of the same name?
A27.	You use the command builtin for this.  For example,
		function cd
		{
			command cd "$@" && title "$PWD"
		}
	will run the builtin command cd from within the function cd
	rather than calling the function cd recursively.

Q28.	How are variables scoped in ksh?
A28.	The scoping of variables was not defined for ksh88 but in ksh93
	static scoping was specified.  For example the output from
		function f1
		{
			print foo=$foo
		}
		function f2
		{
			typeset foo=local
			f1
		}
		foo=global
		f2
	will be "global".  To get f2 to cause f1 to print the local
	value of foo, f2 can run "foo=$foo f1" instead.

Q29.	Can you write a self reproducing program in KornShell?
A29.	Yes, the following program is self reproducing.  Any shorter ones?
n="
" q="'" x="cat <<-!" y=! z='n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y'
cat <<-!
n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y
!
=====================================================

IV.	SHELL EXTENSIONS

Q1.	Is there a shell compiler?
A1.	There is a separate command named shcomp that will convert
	a script into an intermediate machine independent form.  The shell
	will detect this format whenever it runs a script and execute
	directly from this intermediate format. 

Q2.	What is the advantage of making commands built-in?
A2.	The startup time is reduced by a couple of orders of
	magnitude.  In addition, built-in commands can access
	ksh internals.

Q3.	What is the disadvantage of making commands built-in?
A3.	Errors in these built-ins can cause the shell to crash.

Q4.	How do I add built-in commands?
A4.	There are two ways to do this.  One is write a shared library
	with functions whose names are b_xxxx where xxxx is the name of
	the builtin.  The function b_xxxx takes three argument.  The first
	two are the same as a mail program.  The third parameter is
	a pointer argument which will point to the current shell context.
	The second way is to write a shared library with a function named
	lib_init().  This function will be called with an argument of 0
	after the library is loaded.  This function can add built-ins
	with the sh_addbuiltin() API function.  In both cases, the
	library is loaded into the shell with the "builtin" utility.

Q5.	Can ksh93 be embedded?
A5.	Yes, ksh93 can be compiled as a shared or dynamically linked
	library which can be embedded into applications.  There is
	an API for interfacing to shell variables and to several of
	the internal shell functions.

Q6.	Can I write GUI applications with ksh?
A6.	There are two extensions to ksh that can be used to write
	GUI applications as shell script.  One is dtksh which
	was written by Steve Pendergrast at Novell and is
	included with the Common Desktop Environment, CDE.  The other is
	tksh which was written by Jeff Korn.  tksh combines the tk graphics
	package with ksh93 and reimplements the tcl language
	as an extension so that both tcl and ksh scripts
	can run in the same address space.  The source for tksh
	is included in the ast-open package.