From a30e7b7fa985119df1d118555908e957339213bd Mon Sep 17 00:00:00 2001 From: Lefteris Koutsofios Date: Fri, 14 Feb 2020 12:56:21 -0500 Subject: [PATCH] added documentation pages from Dave Korn's old web site --- docs/index.html | 6 + docs/ksh/builtins.html | 710 ++++++++++++++++++ docs/ksh/examples.html | 55 ++ docs/ksh/faq.html | 1004 ++++++++++++++++++++++++++ docs/ksh/features.html | 207 ++++++ docs/ksh/functions/dirs.txt | 111 +++ docs/ksh/functions/emacs_keybind.txt | 12 + docs/ksh/functions/getopt.txt | 28 + docs/ksh/functions/keybind.txt | 14 + docs/ksh/functions/popd.txt | 111 +++ docs/ksh/functions/pushd.txt | 111 +++ docs/ksh/functions/title.txt | 54 ++ docs/ksh/functions/vi_keybind.txt | 10 + docs/ksh/index.html | 10 + docs/ksh/ksh.html | 118 +++ docs/ksh/scripts/cgi-lib.ksh.txt | 129 ++++ docs/ksh/scripts/dump-cgi.ksh.txt | 17 + docs/ksh/scripts/env.txt | 66 ++ docs/ksh/scripts/line.txt | 2 + docs/ksh/scripts/which.txt | 2 + 20 files changed, 2777 insertions(+) create mode 100644 docs/index.html create mode 100644 docs/ksh/builtins.html create mode 100644 docs/ksh/examples.html create mode 100644 docs/ksh/faq.html create mode 100644 docs/ksh/features.html create mode 100644 docs/ksh/functions/dirs.txt create mode 100644 docs/ksh/functions/emacs_keybind.txt create mode 100644 docs/ksh/functions/getopt.txt create mode 100644 docs/ksh/functions/keybind.txt create mode 100644 docs/ksh/functions/popd.txt create mode 100644 docs/ksh/functions/pushd.txt create mode 100644 docs/ksh/functions/title.txt create mode 100644 docs/ksh/functions/vi_keybind.txt create mode 100644 docs/ksh/index.html create mode 100644 docs/ksh/ksh.html create mode 100644 docs/ksh/scripts/cgi-lib.ksh.txt create mode 100644 docs/ksh/scripts/dump-cgi.ksh.txt create mode 100644 docs/ksh/scripts/env.txt create mode 100644 docs/ksh/scripts/line.txt create mode 100644 docs/ksh/scripts/which.txt diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 000000000000..1fedcdc14d09 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,6 @@ + +AST Software + +The KornShell
+ + diff --git a/docs/ksh/builtins.html b/docs/ksh/builtins.html new file mode 100644 index 000000000000..5182b7bdb91f --- /dev/null +++ b/docs/ksh/builtins.html @@ -0,0 +1,710 @@ + + + + + www/ksh/builtins.mm mm document + + + + + +
+ +

+

+

Guidelines for writing ksh-93 built-in commands

+
David G. Korn +

+

+

+

Abstract

+One of the features of ksh93, the latest version of ksh, +is the ability to add built-in commands at run time. +This feature only works on operating systems that have the ability +to load and link code into the current process at run time. +Some examples of the systems that have this feature +are Linux, System V Release 4, Solaris, Sun OS, HP-UX Release 8 and above, +AIX 3.2 and above, and Microsoft Windows systems. +

+This memo describes how to write and compile programs +that can be loaded into ksh at run time as built-in +commands. +

+


INTRODUCTION

+A built-in command is executed without creating a separate process. +Instead, the command is invoked as a C function by ksh. +If this function has no side effects in the shell process, +then the behavior of this built-in is identical to that of +the equivalent stand-alone command. The primary difference +in this case is performance. The overhead of process creation +is eliminated. For commands of short duration, the effect +can be dramatic. For example, on SUN OS 4.1, the time to +run wc on a small file of about 1000 bytes, runs +about 50 times faster as a built-in command. +

+In addition, built-in commands may have side effects on the +shell environment. +This is usually done to extend the application domain for +shell programming. For example, there is a group of X-windows extension +built-ins that make heavy use of the shell variable namespace. +These built-ins are added at run time and +result in a windowing shell that can be used to write +X-windows applications. +

+While there are definite advantages to adding built-in +commands, there are some disadvantages as well. +Since the built-in command and ksh share the same +address space, a coding error in the built-in program +may affect the behavior of ksh; perhaps causing +it to core dump or hang. +Debugging is also more complex since your code is now +a part of a larger entity. +The isolation provided by a separate process +guarantees that all resources used by the command +will be freed when the command completes. +Resources used by a built-in must be meticulously maintained and freed. +Also, since the address space of ksh will be larger when built-in are loaded, +it may increase the time it takes ksh to fork() and +exec() non-built-in commands. +It makes no sense to add a built-in command that takes +a long time to run or that is run only once, since the performance +benefits will be negligible. +Built-ins that have side effects in the current shell +environment have the disadvantage of increasing the +coupling between the built-in and ksh, making +the overall system less modular and more monolithic. +

+Despite these drawbacks, in many cases extending +ksh by adding built-in +commands makes sense and allows reuse of the shell +scripting ability in an application specific domain. +This memo describes how to write ksh extensions. +

+


WRITING BUILT-IN COMMANDS

+There is a development kit available for writing ksh +built-ins as part of the AST (AT&T Software Technology) Toolkit. +The development kit has three directories, +include, lib, and bin. +It is best to set the value of the environment variable +PACKAGE_ast to the pathname of the directory +containing the development kit. +The include directory contains a sub-directory +named ast that contains interface prototypes +for functions that you can call from built-ins. The lib +directory contains the ast library +and a library named cmd that contains a version +of several of the standard POSIX[1] +utilities that can be made run time built-ins. +The lib/ksh directory contains shared libraries +that implement other ksh built-ins. +The bin directory contains build tools such as nmake[2]. +To add built-ins at runtime, it is necessary to build a shared library +containing one or more built-ins that you wish to add. +The built-ins are then added by running builtin -f shared_lib. +Since the procedure for building share libraries is system dependent, +it is best to use +nmake +using the sample nmake makefile below as a prototype. +The AST Toolkit also contains some examples of built-in libraries under +the src/cmd/kshlib directory. +

+There are two ways to code adding built-ins. One method is to replace +the function main with a function +b_name, where name is the name +of the built-in you wish to define. +A built-in command has a calling convention similar to +the main function of a program, +int main(int argc, char *argv[]). +except that it takes a third argument of type Shbltin_t* which can +be passed as NULL if it is not used. The definition for +Shbltin_t* is in <ast/shcmd.h>. +Instead of exit, you need to use return +to terminate your command. +The return value will become the exit status of the command. +The open built-in, installed in lib/ksh in the AST Toolkit, uses this method. +The Shbltin_t structure contains a field named shp which is +a pointer the the shell data that is needed for shell library callbacks. +It also contains the fields, shrun, shtrap, shexit, +and shbltin +that are function pointers to the shell library functions sh_run, sh_trap +sh_exit, and sh_addbuiltin, respectively. These functions +can be invoked without the need for runtime symbol lookup when the +shell is statically linked with libshell. +

+The alternative method is to create a function lib_init and +use the Shbltin_t.shbltin() function to add one or more built-ins. +The lib_init function will be called with two arguments. The +first argument will be 0 when the library is loaded and the second +argument will be of type Shbltin_t*. +The dbm_t and dss shell built-ins use this method. +

+No matter which way you add built-ins you should add the line +SHLIB(identifier) as the last line of one +of the built-in source file, where identifier is any C identifier. +This line provides version information to the shell builtin command +that it uses to verify compatibility between the built-in and ksh +implementation versions. builtin fails with a diagnostic on version +mismatch. The diagnostic helps determine whether ksh is out of +date and requires an upgrade or the built-in is out of date and requires +recompilation. +

+The steps necessary to create and add a run time built-in are +illustrated in the following simple example. +Suppose you wish to add a built-in command named hello +which requires one argument and prints the word hello followed +by its argument. First, write the following program in the file +hello.c: +

+
+#include     <stdio.h>
+int b_hello(int argc, char *argv[], void *context)
+{
+        if(argc != 2)
+        {
+                fprintf(stderr,"Usage: hello arg\n");
+                return(2);
+        }
+        printf("hello %s\n",argv[1]);
+        return(0);
+}
+SHLIB(hello)
+
+ +

+Next, the program needs to be compiled. +If you are building with AT&T nmake use the following Makefile: +

+
+:PACKAGE: --shared ast
+hello plugin=ksh :LIBRARY: hello.c
+
+ +and run nmake install to compile, link, and install the built-in shared library +in lib/ksh/ under PACKAGE_ast. +If the built-in extension uses several .c files, list all of these on +the :LIBRARY: line. +

+Otherwise you will have to compile hello.c with an option +to pick up the AST include directory +(since the AST <stdio.h> is required for ksh compatibility) +and options required for generating shared libraries. +For example, on Linux use this to compile: +

+
+cc -fpic -I$PACKAGE_ast/include/ast -c hello.c
+
+ +and use the appropriate link line. +It really is best to use nmake because the 2 line Makefile above +will work on all systems that have ksh installed. +

+If you have several built-ins, it is desirable +to build a shared library that contains them all. +

+The final step is using the built-in. +This can be done with the ksh command builtin. +To load the shared library libhello.so from the current directory +and add the built-in hello, invoke the command, +

+
+builtin -f ./libhello.so hello
+
+ +The shared library prefix (lib here) and suffix (.so here) be omitted; +the shell will add an appropriate suffix +for the system that it is loading from. +If you install the shared library in lib/ksh/, where ../lib/ksh/ is +a directory on $PATH, the command +
+
+builtin -f hello hello
+
+ +will automatically find, load and install the built-in on any system. +Once this command has been invoked, you can invoke hello +as you do any other command. +If you are using lib_init method to add built-ins then no arguments +follow the -f option. +

+It is often desirable to make a command built-in +the first time that it is referenced. The first +time hello is invoked, ksh should load and execute it, +whereas for subsequent invocations ksh should just execute the built-in. +This can be done by creating a file named hello +with the following contents: +

+
+function hello
+{
+        unset -f hello
+        builtin -f hello hello
+        hello "$@"
+}
+
+ +This file hello needs to be placed in a directory that is +in your FPATH variable, and the built-in shared library +should be installed in lib/ksh/, as described above. +

+


CODING REQUIREMENTS AND CONVENTIONS

+As mentioned above, the entry point for built-ins must either be of +the form b_name or else be loaded from a function named +lib_init. +Your built-ins can call functions from the standard C library, +the ast library, interface functions provided by ksh, +and your own functions. +You should avoid using any global symbols beginning with +sh_, +nv_, +and +ed_ +since these are used by ksh itself. +#define constants in ksh interface +files use symbols beginning with SH_ and NV_, +so avoid using names beginning with these too. +

+

Header Files

+The development kit provides a portable interface +to the C library and to libast. +The header files in the development kit are compatible with +K&R C[3], +ANSI-C[4], +and C++[5]. +

+The best thing to do is to include the header file <shell.h>. +This header file causes the <ast.h> header, the +<error.h> header and the <stak.h> +header to be included as well as defining prototypes +for functions that you can call to get shell +services for your builtins. +The header file <ast.h> +provides prototypes for many libast functions +and all the symbol and function definitions from the +ANSI-C headers, <stddef.h>, +<stdlib.h>, <stdarg.h>, <limits.h>, +and <string.h>. +It also provides all the symbols and definitions for the +POSIX[6] +headers <sys/types.h>, <fcntl.h>, and +<unistd.h>. +You should include <ast.h> instead of one or more of +these headers. +The <error.h> header provides the interface to the error +and option parsing routines defined below. +The <stak.h> header provides the interface to the memory +allocation routines described below. +

+Programs that want to use the information in <sys/stat.h> +should include the file <ls.h> instead. +This provides the complete POSIX interface to stat() +related functions even on non-POSIX systems. +

+

+

Input/Output

+ksh uses sfio, +the Safe/Fast I/O library[7], +to perform all I/O operations. +The sfio library, which is part of libast, +provides a superset of the functionality provided by the standard +I/O library defined in ANSI-C. +If none of the additional functionality is required, +and if you are not familiar with sfio and +you do not want to spend the time learning it, +then you can use sfio via the stdio library +interface. The development kit contains the header <stdio.h> +which maps stdio calls to sfio calls. +In most instances the mapping is done +by macros or inline functions so that there is no overhead. +The man page for the sfio library is in an Appendix. +

+However, there are some very nice extensions and +performance improvements in sfio +and if you plan any major extensions I recommend +that you use it natively. +

+

Error Handling

+For error messages it is best to use the ast library +function errormsg() rather that sending output to +stderr or the equivalent sfstderr directly. +Using errormsg() will make error message appear +more uniform to the user. +Furthermore, using errormsg() should make it easier +to do error message translation for other locales +in future versions of ksh. +

+The first argument to +errormsg() specifies the dictionary in which the string +will be searched for translation. +The second argument to errormsg() contains that error type +and value. The third argument is a printf style format +and the remaining arguments are arguments to be printed +as part of the message. A new-line is inserted at the +end of each message and therefore, should not appear as +part of the format string. +The second argument should be one of the following: +

+
+
ERROR_exit(n):

+If n is not-zero, the builtin will exit value n after +printing the message. +
ERROR_system(n):

+Exit builtin with exit value n after printing the message. +The message will display the message corresponding to errno +enclosed within [ ] at the end of the message. +
ERROR_usage(n):

+Will generate a usage message and exit. If n is non-zero, +the exit value will be 2. Otherwise the exit value will be 0. +
ERROR_debug(n):

+Will print a level n debugging message and will then continue. +
ERROR_warn(n):

+Prints a warning message. n is ignored. +

+

Option Parsing

+The first thing that a built-in should do is to check +the arguments for correctness and to print any usage +messages on standard error. +For consistency with the rest of ksh, it is best +to use the libast functions optget() and +optusage()for this +purpose. +The header <error.h> includes prototypes for +these functions. +The optget() function is similar to the +System V C library function getopt(), +but provides some additional capabilities. +Built-ins that use optget() provide a more +consistent user interface. +

+The optget() function is invoked as +

+
+int optget(char *argv[], const char *optstring)
+
+ +where argv is the argument list and optstring +is a string that specifies the allowable arguments and +additional information that is used to format usage +messages. +In fact a complete man page in troff or html +can be generated by passing a usage string as described +by the getopts command. +Like getopt(), +single letter options are represented by the letter itself, +and options that take a string argument are followed by the : +character. +Option strings have the following special characters: +
+
+
:
+Used after a letter option to indicate that the option +takes an option argument. +The variable opt_info.arg will point to this +value after the given argument is encountered. +
#
+Used after a letter option to indicate that the option +can only take a numerical value. +The variable opt_info.num will contain this +value after the given argument is encountered. +
?
+Used after a : or # (and after the optional ?) +to indicate the the +preceding option argument is not required. +
[...]

+After a : or #, the characters contained +inside the brackets are used to identify the option +argument when generating a usage message. +
space

+The remainder of the string will only be used when generating +usage messages. +
+
+

+The optget() function returns the matching option letter if +one of the legal option is matched. +Otherwise, optget() returns +

+
+
':'
+If there is an error. In this case the variable opt_info.arg +contains the error string. +
0
+Indicates the end of options. +The variable opt_info.index contains the number of arguments +processed. +
'?'
+A usage message has been required. +You normally call optusage() to generate and display +the usage message. +
+
+

+The following is an example of the option parsing portion +of the wc utility. +

+
+#include <shell.h>
+while(1) switch(n=optget(argv,"xf:[file]"))
+{
+	case 'f':
+		file = opt_info.arg;
+		break;
+	case ':':
+		error(ERROR_exit(0), opt_info.arg);
+		break;
+	case '?':
+		error(ERROR_usage(2), opt_info.arg);
+		break;
+}
+
+ +

+

Storage Management

+It is important that any memory used by your built-in +be returned. Otherwise, if your built-in is called frequently, +ksh will eventually run out of memory. +You should avoid using malloc() for memory that must +be freed before returning from you built-in, because by default, +ksh will terminate you built-in in the event of an +interrupt and the memory will not be freed. +

+The best way to to allocate variable sized storage is +through calls to the stak library +which is included in libast +and which is used extensively by ksh itself. +Objects allocated with the stakalloc() +function are freed when you function completes +or aborts. +The stak library provides a convenient way to +build variable length strings and other objects dynamically. +The man page for the stak library is contained +in the Appendix. +

+Before ksh calls each built-in command, it saves +the current stack location and restores it after +it returns. +It is not necessary to save and restore the stack +location in the b_ entry function, +but you may want to write functions that use this stack +are restore it when leaving the function. +The following coding convention will do this in +an efficient manner: +

+
+yourfunction()
+{
+        char	*savebase;
+        int	saveoffset;
+        if(saveoffset=staktell())
+        	savebase = stakfreeze(0);
+        ...
+        if(saveoffset)
+        	stakset(savebase,saveoffset);
+        else
+        	stakseek(0);
+}
+
+ +

+


CALLING ksh SERVICES

+Some of the more interesting applications are those that extend +the functionality of ksh in application specific directions. +A prime example of this is the X-windows extension which adds +builtins to create and delete widgets. +The nval library is used to interface with the shell +name space. +The shell library is used to access other shell services. +

+

The nval library

+A great deal of power is derived from the ability to use +portions of the hierarchal variable namespace provided by ksh-93 +and turn these names into active objects. +

+The nval library is used to interface with shell +variables. +A man page for this file is provided in an Appendix. +You need to include the header <nval.h> +to access the functions defined in the nval library. +All the functions provided by the nval library begin +with the prefix nv_. +Each shell variable is an object in an associative table +that is referenced by name. +The type Namval_t* is pointer to a shell variable. +To operate on a shell variable, you first get a handle +to the variable with the nv_open() function +and then supply the handle returned as the first +argument of the function that provides an operation +on the variable. +You must call nv_close() when you are finished +using this handle so that the space can be freed once +the value is unset. +The two most frequent operations are to get the value of +the variable, and to assign value to the variable. +The nv_getval() returns a pointer the the +value of the variable. +In some cases the pointer returned is to a region that +will be overwritten by the next nv_getval() call +so that if the value isn't used immediately, it should +be copied. +Many variables can also generate a numeric value. +The nv_getnum() function returns a numeric +value for the given variable pointer, calling the +arithmetic evaluator if necessary. +

+The nv_putval() function is used to assign a new +value to a given variable. +The second argument to putval() is the value +to be assigned +and the third argument is a flag which +is used in interpreting the second argument. +

+Each shell variable can have one or more attributes. +The nv_isattr() is used to test for the existence +of one or more attributes. +See the appendix for a complete list of attributes. +

+By default, each shell variable passively stores the string you +give with with nv_putval(), and returns the value +with getval(). However, it is possible to turn +any node into an active entity by assigning functions +to it that will be called whenever nv_putval() +and/or nv_getval() is called. +In fact there are up to five functions that can +associated with each variable to override the +default actions. +The type Namfun_t is used to define these functions. +Only those that are non-NULL override the +default actions. +To override the default actions, you must allocate an +instance of Namfun_t, and then assign +the functions that you wish to override. +The putval() +function is called by the nv_putval() function. +A NULL for the value argument +indicates a request to unset the variable. +The type argument might contain the NV_INTEGER +bit so you should be prepared to do a conversion if +necessary. +The getval() +function is called by nv_getval() +value and must return a string. +The getnum() +function is called by by the arithmetic evaluator +and must return double. +If omitted, then it will call nv_getval() and +convert the result to a number. +

+The functionality of a variable can further be increased +by adding discipline functions that +can be associated with the variable. +A discipline function allows a script that uses your +variable to define functions whose name is +varname.discname +where varname is the name of the variable, and discname +is the name of the discipline. +When the user defines such a function, the settrap() +function will be called with the name of the discipline and +a pointer to the parse tree corresponding to the discipline +function. +The application determines when these functions are actually +executed. +By default, ksh defines get, +set, and unset as discipline functions. +

+In addition, it is possible to provide a data area that +will be passed as an argument to +each of these functions whenever any of these functions are called. +To have private data, you need to define and allocate a structure +that looks like +

+
+struct yours
+{
+        Namfun_t	fun;
+	your_data_fields;
+};
+
+ +

+

The shell library

+There are several functions that are used by ksh itself +that can also be called from built-in commands. +The man page for these routines are in the Appendix. +

+The sh_addbuiltin() function can be used to add or delete +builtin commands. It takes the name of the built-in, the +address of the function that implements the built-in, and +a void* pointer that will be passed to this function +as the third agument whenever it is invoked. +If the function address is NULL, the specified built-in +will be deleted. However, special built-in functions cannot +be deleted or modified. +

+The sh_fmtq() function takes a string and returns +a string that is quoted as necessary so that it can +be used as shell input. +This function is used to implement the %q option +of the shell built-in printf command. +

+The sh_parse() function returns a parse tree corresponding +to a give file stream. The tree can be executed by supplying +it as the first argument to +the sh_trap() function and giving a value of 1 as the +second argument. +Alternatively, the sh_trap() function can parse and execute +a string by passing the string as the first argument and giving 0 +as the second argument. +

+The sh_isoption() function can be used to set to see whether one +or more of the option settings is enabled. +

+


References

+

+

+ +
[1]
+POSIX - Part 2: Shell and Utilities, +IEEE Std 1003.2-1992, ISO/IEC 9945-2:1993. +
[2]
+Glenn Fowler, +A Case for make, +Software - Practice and Experience, Vol. 20 No. S1, pp. 30-46, June 1990. +
[3]
+Brian W. Kernighan and Dennis M. Ritchie, +The C Programming Language, +Prentice Hall, 1978. +
[4]
+American National Standard for Information Systems - Programming +Language - C, ANSI X3.159-1989. +
[5]
+Bjarne Stroustroup, +C++, +Addison Wesley, xxxx +
[6]
+POSIX - Part 1: System Application Program Interface, +IEEE Std 1003.1-1990, ISO/IEC 9945-1:1990. +
[7]
+David Korn and Kiem-Phong Vo, +SFIO - A Safe/Fast Input/Output library, +Proceedings of the Summer Usenix, +pp. , 1991. +
+

+


+ + + + + + +
March 13, 2012
+

+ +

+ + + diff --git a/docs/ksh/examples.html b/docs/ksh/examples.html new file mode 100644 index 000000000000..e17bc007f1bb --- /dev/null +++ b/docs/ksh/examples.html @@ -0,0 +1,55 @@ + + + + + www/ksh/examples.mm mm document + + + + + +
+ + + +

+

Sample Functions

+

+ + + + +
+dirs    getopt    popd    title
+emacs_keybind    keybind    pushd    vi_keybind
+ +

+


Sample Scripts

+

+ + + + +
+cgi-lib.ksh    env    which     
+dump-cgi.ksh    line          
+

+


+ + + + + + +
March 13, 2012
+

+ +

+ + + diff --git a/docs/ksh/faq.html b/docs/ksh/faq.html new file mode 100644 index 000000000000..090b059970dc --- /dev/null +++ b/docs/ksh/faq.html @@ -0,0 +1,1004 @@ + + + + + general shell + + + + + + +
+ +

+

general

+
+
+ +
What is KornShell?
+ +KornShell is a command and scripting language that is a superset of the System V UNIX shell, +aka, BourneShell (or +sh). + +
What is ksh?
+ +ksh is the name of the program that implements the KornShell language. + +
What is the history of ksh?
+ +ksh was written by David Korn at Bell Telephone Laboratories. +David Korn is currently at AT&T Research. +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. + +
Where is the official description of the KornShell language?
+ +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. +There are many new features since this book was published and +the man page for ksh93 is kept up to date. + +
What are the major new features of KornShell 1993?
+ +The only major new interactive features are key binding and tab completion. +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. The ability to define types was added in 2009. +In addition, ksh93 has been written to be +extensible with an C language API for programming extensions. + +
Are any further releases of ksh planned?
+ +Yes, the KornShell language and ksh implementation are in active development. +Most of the focus will be on scripting and reusability. + +
Why are newer release of ksh still called ksh93?
+ +We started the AST/ksh OpenSource release process in the late 90's. +At that point ksh93 was the well-known name for ksh. +The OpenSource release was finally granted in March 2000. +No one has since volunteered to repeat that process for kshXX. + +
How can I determine the release or version of a particular ksh?
+ +The current version and release string may be accessed by +${.sh.version} +and +$KSH_VERSION. +The format is Version features 93version[-/+] release: +
    +
  • +features -- +compile time features, typically enabled by SHOPT_foo state variables in the +ksh93 Makefile. +A single letter represents each feature: +
      +
    • +A +(SHOPT_AUDIT) +
    • +B +(SHOPT_BASH) +bash compatibility mode. +
    • +J +(SHOPT_COSHELL) +-lcoshell job pools. +
    • +j +(SHOPT_BGX) +
    • +L +(SHOPT_ACCT) +
    • +M +(SHOPT_MULTIBYTE) +
    • +P +(SHOPT_PFSH) +
    • +R +(SHOPT_REGRESS) +
    +
  • +version-- +a lower-case letter signifying major release points. +An optional - following features signifies an alpha release. +The first stable release has no -. +An optional + signifies a stable release with bug patches and minor enhancements. +
  • +release-- +the release date in YYYY-MM-DD form. +This date corresponds to AST package and git repository releases. +
+KSH_VERSION +in a numeric context is an integer that encodes the release +YYYYMMDD. + +
What new features are planned for ksh?
+ +We are in the early stage of planning but the likely additions +are namespaces, ability to read xml and json object into shell variables, +and handling of queued signals. +Support for multi-threading is also being considered. + +
Is KornShell public domain?
+ +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, in zsh and mksh, and in pdksh, a public domain +implementation. + +
Is ksh public domain?
+ +No, earlier versions were owned by both AT&T and Novell. +The 1993 version is owned by both Lucent and AT&T. + +
Is source code available?
+ +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 +github page. + +
What are the licensing terms?
+ +The exact license terms can be found on the +licence page. + +
Does the license allow binaries to be freely redistributed?
+ +Yes, provided you make the license terms available to +everyone you distribute binaries to. + +
If I make changes to the code, do I have to make them public?
+ +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. + +
Why do some vendors still ship ksh88, not ksh93?
+ +Since ksh88 was included in System V release 4, most vendors +have just included this version. However most Linux systems +and Mac OS provide ksh93 version 's' or later. Solaris11 uses +ksh93 as /bin/sh. + +
Do you provide support for ksh?
+ +No, we will try to fix any bugs we hear about in future +releases, but we do not provide any official support. + +
Is ksh supported commercially?
+ +Software vendors that supply ksh with +their systems typically support it for that system. + +
What is pdksh and is it related to ksh or KornShell?
+ +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. + +
How is the MKS Toolkit KornShell related to KornShell?
+ +MKS Tookit KornShell is a completely independent implementation +that supports a subset of the 1988 KornShell language. + +
What systems does ksh run on?
+ +ksh has been written to be portable. +It has been ported to virtually run on 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, + +
Does ksh conform to the IEEE POSIX and ISO shell standard?
+ +The 1993 version should conform to the 1992 standard. +At one point it had passed the test suite created by X/OPEN. + +
Will KornShell 88 scripts run with KornShell 93?
+ +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. + +
Can ksh run as /bin/sh?
+ +We have installed ksh as /bin/sh on several systems without +encountering any problems. It is /bin/sh on Solaris11. +Our Linux systems use this instead of bash. + +
+
+ +

+


interactive

+
+
+ +
How do I get separate history files for shell?
+ +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. + +
How do I get the time of day in my prompt?
+ +You can use printf with supports the %T format for time and date formatting. +For example, the format %(%H:%M:%S)T specifies time in hour, minute, second +format and if no argument is specifed, the current time is used. Thus setting +PS1='$(printf "%(%H:%M:%S)T" $' will output the time of day before the +$ prompt. + +
Why does the screen width not function correctly when non-printing characters are in my prompt?
+ +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. + +
What is the PS4 prompt and how is it used?
+ +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. + +
How is keybinding done?
+ +ksh93 provides a KEYBD trap that gets executed whenever a key +is entered from the keyboard. +Using this trap, and the associative +array feature of ksh93, a keybind function can easily be written +which will map any entered key sequence to another key sequence. + +
How do I get the arrow keys to work?
+ +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. + +
Does ksh support file name completion?
+ +Yes, it does. +The default key binding is <ESC><ESC> +however, starting with the 'g' point release, <TAB> also works +for completion. + +
Does ksh support command completion?
+ +If you perform completion on the first word of a command, +ksh will do completion using aliases, functions, and commands. + +
Is completion programmable?
+ +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. + +
Is there any way to get the command-line editor to go to more than a single line?
+ +The multiline option (now on by default) allows lines longer than the width +of the screen to be displayed on multiple lines on the screen. +Also 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. + +
What is predictive editing?
+In 2010, a compile option was added that cause the shell to try to predict +what you were trying to type by looking in the history file for all lines +that matched and presenting them as a menu. Any line starting with # would +use the characters you type to find matching lines from the history file. +If you find the line you wanted, you can enter the number followed by +<TAB> or newline. However bugs in earlier version led to core dumps. + + +
Can I use the shell line editor on other commands?
+ +The command ie, that comes along with shell, can be used +to run line input oriented commands with command line editing. + +
When I do echo $?, I am getting 267. What does this mean?
+ +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. + +
When I type builtin, I notice that some of these are full pathnames. What does this mean?
+ +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. + +
What is a self generating man page?
+ +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. +All self-documenting output is to the standard error, +so you must redirect 2>... to capture the output. +

+This same method can also be used for shell scripts. +Run +getopts --man +for more details. + +

What is autoloading?
+ +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. + +
Why does the output from 'time command 2> file' come out on the screen?
+ +The time command is a compound command in ksh and time is a reserved +word It can be followed by any pipeline. Thus, redirections applied +at the end are for the command, not to time itself. You can use +time {...;} 2> file to capture the timing output to a file. Note, +that with ksh, time works with all commands, for example, +time for i; do xxx;done. + +
When I run 'mv * ../elsewhere' I so that get '-ksh: mv: cannot execute [Arg list too long]', what causes this?
+ +UNIX sytems have a limit to the space consumed by command arguments and +environment variables when running commands that are not built into +the shell. The configuration parameter ARG_MAX defines this limit. +You can run 'getconf ARG_MAX' to find the limit for your system. Note +that the shell expands * to the list of files in the current directory +before running mv. In many case the xargs or tw command can be +used to work around this problem by splitting the line into chunks +and invoking the command. Another way to work around this limit +is to make the command a builtin. On systems in which the cmd +library is installed, you can invoke 'builtin -f cmd mv' to make +mv a shell builtin in which case the line length limit no longer +applies. Another alternative is to use a for loop and invoke +the mv command for each file, for exampe, +'for i in *;do mv $i ../elsewhere;done'. +Starting with ksh93o+, a new feature was added to ksh to overcome +this limit in some cases. If a command is preceded by +'command -x', and it fails because there are two many arguments, +the command will be run multiple times with subsets of the arguments. +However, the change in ksh93o+ does not work in the above case +because the ../elsewhere is not used for each subset. This problem +was resolved starting in ksh93p so that +command -x mv * ../elsewhere +should work. Note that it is possible to do alias mv='command -x mv' + +
Is there any way to generate the list of .c files in the current directory and all the subdirectories?
+ +Starting with ksh93o+, the globstar option (set -G or set -o globstar) +was added. With globstar enabled, ** by itself matches zero or more +directories or files, and **/ matches zero or more directories so that +**/*.c will match all .c files under the current directory. + +
Is there any way to prevent sending a HUP signal to a job when I log out if I didn't nohup the job?
+ +Yes, the disown command tells ksh not to forward the HUP signal +to the specified jobs when it disconnects. + +
+
+ +

+


programming

+
+
+ +
What is the difference between * and @, for example, and ?
+ +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. + +
Why do I need spaces around { and } but not around ( and )?
+ +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. + +
How do I get read to maintain the \ characters?
+ +Use read -r instead. + +
How can I a write a ksh script that responds directly to each character so that you user just has to enter y, not y<return>?
+ +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}$'
+}
+trap keytrap KEYBD
+
+ +and then +
+
+read x
+
+ + +
What is the purpose of $'...'?
+ +The $'...' string literal syntax 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 backward compatible. + +
What is the -n option used for?
+ +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. + +
Why are both `...` and $(...) used for command substitution?
+ +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. + +
How can I tell if all the commands of a pipeline have succeeded?
+ +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. + +
What is the difference between [...] and [[...]]?
+ +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. You should use [[...]] instead of [...] and test. + +
How come [[ $foo == $bar ]] is true and [[ $bar == $foo ]] is false?
+ +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. + +
Why does ksh93 have print since echo already exists is is widely used?
+ +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. + +
What is $bar after running 'echo foo | read bar'?
+ +The answer 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). + +
How can I access a substring of a variable?
+ +The syntax ${varname:offset:len} can be used to generate +the string of length len starting at the the specified +offset. String offsets start at 0. If :len is omitted, +then the remainder of the string will be used. Both offset +and len can be arithmetic expressions. A negative offset is +subtracted from the last offset. + +
What is the difference between ((expr)) and $((expr))?
+ +((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 permitted. +

+ +

What is the difference between $((x*y)) and $(($x*$y))?
+ +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
+When x and y are numeric the first form is recommended for better
+performance.
+
+ + +
How do I handle filenames with spaces in them?
+ +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. + +
What are active variables?
+ +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. + +
What is the difference between function name and name()?
+ +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. + +
What is the naming conventions for files in FPATH and can one file contain more than one function definition?
+ +You can have more than one function defined in each file defined +in FPATH and all of them will be added to the list of known +functions. Any commands placed in this file outside of function +definitions will be invoked first. The name of the file must be +that of the first function you invoke. If you have several functions +defined in one file, than you should create a link to each of the +function names that can potentially be invoked first. + +
What are name reference variables and how are they used?
+ +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. + +
If i=1 and var1=some value, how do I print var$i to get its value?
+ +Either use +
+
+eval print var\$i
+
+ +or +
+
+typeset -n x=var$i
+print $x
+
+ + +
How can I shift the elements of an array?
+ +The shift special builtin-command only works for positional +parameters. +However, noting that array subscripts start at 0, you can use +
+
+typeset -A name "${name[@]:1}"
+
+ +to shift the array. + +
Why are the braces required with array references, e.g. ${x[1]}?
+ +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. + +
How do I get the list of subscript names for an associative array?
+ +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[@]}. + +
How do I do global substitutions on the contents of shell variables?
+ +Use // instead of / for global substitution, ${var//aa/bb} will +expand to the value of with each "aa" replace by "bb". + +
How can I convert %XX values to ascii?
+ +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. + +
I want to use exec to open a file. How do I prevent the script from exiting if the exec fails?
+ +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. + +
How do I execute a builtin inside a function of the same name?
+ +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. + +
How are variables scoped in ksh?
+ +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. + +
Can you write a self reproducing program in KornShell?
+ +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
+!
+
+ + +
+
+ +

+


redirections

+
+
+ +
How do I redirect both standard input and standard output to a file?
+ +Add the following redirections to the command. +> file 2> &1. +This will redirect standard output (file descriptor 1) to "file" and +standard error (file descriptor 2) to the same place as file descriptor 1. +ksh redirection allows you to redirect any single digit file descriptor +by putting the descriptor number in front of the redirection operator +with no intervening space. + +
Is there a way for the shell to pick the file number when I open a file?
+ +Yes, a redirection operator operator can be preceded by {n} without any +intervening space where n is the name of a variable. The file descriptor +will be placed in variable n. + +
How do I connect to a socket from a shell script?
+ +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. + +
How do I seek to a given location in a file?
+ +The redirection operators <# and ># allow you to seek to a specified +location in a file. The operator can be followed by an arithmetic +expression contained in ((...)). The variables CUR and EOF can be used +in the arithmetic expression to get relative locations or locations +relative to the end of file respectively. +Alternatively, <# and ># can be followed by a shell pattern. In this +case, the file will be positioned to beginning of the next line +containing this pattern. + +
What is the the <<< redirection operator?
+ +It denotes a here-document in which the document is contained the +argument that follows <<< and therefore there is no delimiter. + +
What is the the >; redirection operator?
+ +This operator writes the output into a temporary file in the same +directory as the file specified after >;. If the command completes +successfully, then the the file is replaced. Otherwise, the +original file is unchanged and the temporary file removed. + +
What is the the <>; redirection operator?
+ +The file is opened for reading and writing as with <>. However, +when the file is closed it is truncated to the its current location. + +
+
+ +

+


extensions

+
+
+ +
Is there a shell compiler?
+ +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. + +
What is the advantage of making commands built-in?
+ +The startup time is reduced by a couple of orders of magnitude. +In addition, built-in commands can access ksh internals. + +
What is the disadvantage of making commands built-in?
+ +Errors in these built-ins can cause the shell to crash. + +
How do I add built-in commands?
+ +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 arguments. +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. + +
Can ksh93 be embedded?
+ +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. + +
Can I write GUI applications with ksh?
+ +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. + +
+
+ + + + + +
show all answershide all answers
+

+


+ + + + + + +
June 19, 2012
+

+ +

+ + + diff --git a/docs/ksh/features.html b/docs/ksh/features.html new file mode 100644 index 000000000000..8c3abe0dd9b8 --- /dev/null +++ b/docs/ksh/features.html @@ -0,0 +1,207 @@ + + + + + www/ksh/features.mm mm document + + + + + +
+ + + +

+

ksh features

+KSH-93 is the most recent version of the KornShell Language described in +The KornShell Command and Programming Language, +by Morris Bolsky and David Korn of AT&T Research (nee Bell Laboratories). +The KornShell is a shell programming language, +which is upward compatible with +sh +(the Bourne Shell), +and is intended to conform to the IEEE P1003.2/ISO 9945.2 Shell and +Utilities standard. +KSH-93 provides an enhanced programming environment in +addition to the major command-entry features of the BSD +shell +csh. +With KSH-93, medium-sized programming tasks can be +performed at shell-level without a significant loss in performance. +In addition, +sh +scripts can be run on KSH-93 without modification. +

+The code should conform to the IEEE POSIX 1003.1 standard and to the +proposed ANSI-C standard so that it should be portable to all +such systems. +Like the previous version, KSH-88, +it is designed to accept eight bit character sets +transparently, thereby making it internationally compatible. +It can support multi-byte characters sets with some characteristics +of the character set given at run time. +

+KSH-93 provides the following features, many of which were also inherent +in KSH-88: + +

+

Enhanced Command Re-entry Capability

+The KSH-93 history +function records commands entered at any shell level and stores +them, up to a user-specified limit, even after you log off. +This allows you to re-enter long commands with a few keystrokes +- even those commands you entered yesterday. +The history file allows for eight bit characters in +commands and supports essentially unlimited size histories. + +

+

In-line Editing

+In +sh +the only way to fix mistyped +commands is to backspace or retype the line. +KSH-93 allows you +to edit a command line using a choice of EMACS-TC or +vi +functions. +You can use the in-line editors to complete filenames as +you type them. +You may also use this editing feature when entering +command lines from your history file. +A user can capture keystrokes and rebind keys to customize the +editing interface. + +

+

Extended I/O Capabilities

+KSH-93 provides several I/O +capabilities not available in +sh, +including the ability to: +
    +
  • +specify a file descriptor for input and output +
  • +start up and run co-processes +
  • +produce a prompt at the terminal before a read +
  • +easily format and interpret responses to a menu +
  • +echo lines exactly as output without escape processing +
  • +format output using printf formats. +
  • +read and echo lines ending in "\e". +
+ +

+

Improved performance

+KSH-93 executes many scripts faster +than the System V Bourne shell. +A major reason for this is +that many of the standard utilities are built-in. +To reduce the time to initiate a command, KSH-93 allows +commands to be added as built-ins at run time +on systems that support dynamic loading such as System V Release 4. + +

+

Arithmetic

+KSH-93 allows you to do integer arithmetic in any +base from two to sixty-four. +You can also do double +precision floating point arithmetic. +Almost the complete set of C language operators are available +with the same syntax and precedence. +Arithmetic expressions can be used to as an argument expansion +or as a separate command. +In addition there is an arithmetic for command that works +like the for statement in C. + +

+

Arrays

+KSH-93 supports both indexed and associative arrays. +The subscript for an indexed array is an arithmetic expression, +whereas, the subscript for an associative array is a string. + +

+

Functions and Aliases

+Two mechanisms - functions and +aliases - can be used to assign a user-selected identifier to +an existing command or shell script. +Functions allow local variables and provide scoping +for exception handling. +Functions can be searched for and loaded on first reference the +way scripts are. + +

+

Substring Capabilities

+KSH-93 allows you to create a +substring of any given string either by specifying the starting +offset and length, or by stripping off leading +or trailing substrings during parameter substitution. +You can also specify attributes, such as upper and lower case, +field width, and justification to shell variables. + +

+

Enhanced pattern matching capabilities

+KSH-93 allows you to specify +regular expressions for file and string matches. + +

+

Improved debugging

+KSH-93 can generate line numbers on execution traces. +Also, I/O redirections are now traced. +There is a DEBUG trap that gets evaluated after each command +so that errors can be localized. + +

+

Job Control

+On systems that support job control, including +System V Release 4, KSH-93 +provides a job-control mechanism almost identical to that of +the BSD "csh", version 4.1. +This feature allows you +to stop and restart programs, and to move programs between the +foreground and the background. + +

+

Added security

+KSH-93 can execute scripts which do not have read permission +and scripts which have the setuid and/or setgid set when +invoked by name, rather than as an argument to the shell. +It is possible to log or control the execution of setuid and/or +setgid scripts. +The noclobber option prevents you from accidentally erasing +a file by redirecting to an existing file. + +

+

Documentation

+Documentation for KSH-93 consists of an +Introduction to KSH-93, +Compatibility with the Bourne Shell, +a manual page and a +README file. +In addition, the +New KornShell Command and Programming Language +book is available from Prentice Hall. +

+


+ + + + + + +
March 13, 2012
+

+ +

+ + + diff --git a/docs/ksh/functions/dirs.txt b/docs/ksh/functions/dirs.txt new file mode 100644 index 000000000000..1bc9346f40b3 --- /dev/null +++ b/docs/ksh/functions/dirs.txt @@ -0,0 +1,111 @@ +# +# DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS +# +# Uses global parameters _push_max _push_top _push_stack +integer _push_max=100 _push_top=100 +# Display directory stack -- $HOME displayed as ~ +function dirs +{ + typeset dir="${PWD#$HOME/}" + case $dir in + $HOME) + dir=\~ + ;; + /*) ;; + *) dir=\~/$dir + esac + print -r - "$dir ${_push_stack[@]}" +} + +# Change directory and put directory on front of stack +function pushd +{ + typeset dir= type=0 + integer i + case $1 in + "") # pushd + if ((_push_top >= _push_max)) + then print pushd: No other directory. + return 1 + fi + type=1 dir=${_push_stack[_push_top]} + ;; + +[1-9]|+[1-9][0-9]) # pushd +n + integer i=_push_top$1-1 + if ((i >= _push_max)) + then print pushd: Directory stack not that deep. + return 1 + fi + type=2 dir=${_push_stack[i]} + ;; + *) if ((_push_top <= 0)) + then print pushd: Directory stack overflow. + return 1 + fi + esac + case $dir in + \~*) dir=$HOME${dir#\~} + esac + cd "${dir:-$1}" > /dev/null || return 1 + dir=${OLDPWD#$HOME/} + case $dir in + $HOME) + dir=\~ + ;; + /*) ;; + *) dir=\~/$dir + esac + case $type in + 0) # pushd name + _push_stack[_push_top=_push_top-1]=$dir + ;; + 1) # pushd + _push_stack[_push_top]=$dir + ;; + 2) # push +n + type=${1#+} i=_push_top-1 + set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}" + shift $type + for dir + do (((i=i+1) < _push_max)) || break + _push_stack[i]=$dir + done + esac + dirs +} + +# Pops the top directory +function popd +{ + typeset dir + if ((_push_top >= _push_max)) + then print popd: Nothing to pop. + return 1 + fi + case $1 in + "") + dir=${_push_stack[_push_top]} + case $dir in + \~*) dir=$HOME${dir#\~} + esac + cd "$dir" || return 1 + ;; + +[1-9]|+[1-9][0-9]) + typeset savedir + integer i=_push_top$1-1 + if ((i >= _push_max)) + then print pushd: Directory stack not that deep. + return 1 + fi + while ((i > _push_top)) + do _push_stack[i]=${_push_stack[i-1]} + i=i-1 + done + ;; + *) print pushd: Bad directory. + return 1 + esac + unset '_push_stack[_push_top]' + _push_top=_push_top+1 + dirs +} diff --git a/docs/ksh/functions/emacs_keybind.txt b/docs/ksh/functions/emacs_keybind.txt new file mode 100644 index 000000000000..1f2b8b747336 --- /dev/null +++ b/docs/ksh/functions/emacs_keybind.txt @@ -0,0 +1,12 @@ +typeset -A Keytable +trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD +function emacs_keybind +{ + keybind $'\E[A' $'\020' # Up key + keybind $'\E[B' $'\016' # Down key + keybind $'\E[C' $'\06' # Right key + keybind $'\E[D' $'\02' # Left key + keybind $'\E[H' $'\01' # Home key + keybind $'\E[Y' $'\05' # End key + keybind $'\t' $'\E\E' # Tab for command-line completion +} diff --git a/docs/ksh/functions/getopt.txt b/docs/ksh/functions/getopt.txt new file mode 100644 index 000000000000..fe1e97fb045b --- /dev/null +++ b/docs/ksh/functions/getopt.txt @@ -0,0 +1,28 @@ +function getopt +{ + typeset c optstring=$1 options= sep= + shift + while getopts $optstring c + do case $c in + [:?]) + exit 2 + ;; + *) + options="$options$sep-$c" + sep=' ' + if [[ $optstring == *$c:* ]] + then options=" $options $OPTARG" + fi + #then print -rn -- " -$c" "$OPTARG" + #else print -rn -- " -$c" + ;; + esac + done + print -rn -- "$options" + if [[ ${@:$OPTIND-1} != -- ]] + then print -rn -- " --" + fi + if [[ -n ${@:$OPTIND} ]] + then print -r -- " ${@:$OPTIND}" + fi +} diff --git a/docs/ksh/functions/keybind.txt b/docs/ksh/functions/keybind.txt new file mode 100644 index 000000000000..501170a73ec9 --- /dev/null +++ b/docs/ksh/functions/keybind.txt @@ -0,0 +1,14 @@ +typeset -A Keytable +trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD +function keybind # key action +{ + typeset key=$(print -f "%q" "$2") + case $# in + 2) Keytable[$1]='.sh.edchar=${.sh.edmode}'"$key" + ;; + 1) unset Keytable[$1] + ;; + *) print -u2 "Usage: $0 key [action]" + ;; + esac +} diff --git a/docs/ksh/functions/popd.txt b/docs/ksh/functions/popd.txt new file mode 100644 index 000000000000..4924c161673f --- /dev/null +++ b/docs/ksh/functions/popd.txt @@ -0,0 +1,111 @@ +# +# DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS +# +# Uses global parameters _push_max _push_top _push_stack +integer _push_max=100 _push_top=100 +# Display directory stack -- $HOME displayed as ~ +function dirs +{ + typeset dir="${PWD#$HOME/}" + case $dir in + $HOME) + dir=\~ + ;; + /*) ;; + *) dir=\~/$dir + esac + print -r - "$dir ${_push_stack[@]}" +} + +# Change directory and put directory on front of stack +function pushd +{ + typeset dir= type=0 + integer i + case $1 in + "") # pushd + if ((_push_top >= _push_max)) + then print pushd: No other directory. + return 1 + fi + type=1 dir=${_push_stack[_push_top]} + ;; + +[1-9]|+[1-9][0-9]) # pushd +n + integer i=_push_top$1-1 + if ((i >= _push_max)) + then print pushd: Directory stack not that deep. + return 1 + fi + type=2 dir=${_push_stack[i]} + ;; + *) if ((_push_top <= 0)) + then print pushd: Directory stack overflow. + return 1 + fi + esac + case $dir in + \~*) dir=$HOME${dir#~} + esac + cd "${dir:-$1}" > /dev/null || return 1 + dir=${OLDPWD#$HOME/} + case $dir in + $HOME) + dir=\~ + ;; + /*) ;; + *) dir=\~/$dir + esac + case $type in + 0) # pushd name + _push_stack[_push_top=_push_top-1]=$dir + ;; + 1) # pushd + _push_stack[_push_top]=$dir + ;; + 2) # push +n + type=${1#+} i=_push_top-1 + set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}" + shift $type + for dir + do (((i=i+1) < _push_max)) || break + _push_stack[i]=$dir + done + esac + dirs +} + +# Pops the top directory +function popd +{ + typeset dir + if ((_push_top >= _push_max)) + then print popd: Nothing to pop. + return 1 + fi + case $1 in + "") + dir=${_push_stack[_push_top]} + case $dir in + \~*) dir=$HOME${dir#~} + esac + cd "$dir" || return 1 + ;; + +[1-9]|+[1-9][0-9]) + typeset savedir + integer i=_push_top$1-1 + if ((i >= _push_max)) + then print pushd: Directory stack not that deep. + return 1 + fi + while ((i > _push_top)) + do _push_stack[i]=${_push_stack[i-1]} + i=i-1 + done + ;; + *) print pushd: Bad directory. + return 1 + esac + unset '_push_stack[_push_top]' + _push_top=_push_top+1 + dirs +} diff --git a/docs/ksh/functions/pushd.txt b/docs/ksh/functions/pushd.txt new file mode 100644 index 000000000000..1bc9346f40b3 --- /dev/null +++ b/docs/ksh/functions/pushd.txt @@ -0,0 +1,111 @@ +# +# DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS +# +# Uses global parameters _push_max _push_top _push_stack +integer _push_max=100 _push_top=100 +# Display directory stack -- $HOME displayed as ~ +function dirs +{ + typeset dir="${PWD#$HOME/}" + case $dir in + $HOME) + dir=\~ + ;; + /*) ;; + *) dir=\~/$dir + esac + print -r - "$dir ${_push_stack[@]}" +} + +# Change directory and put directory on front of stack +function pushd +{ + typeset dir= type=0 + integer i + case $1 in + "") # pushd + if ((_push_top >= _push_max)) + then print pushd: No other directory. + return 1 + fi + type=1 dir=${_push_stack[_push_top]} + ;; + +[1-9]|+[1-9][0-9]) # pushd +n + integer i=_push_top$1-1 + if ((i >= _push_max)) + then print pushd: Directory stack not that deep. + return 1 + fi + type=2 dir=${_push_stack[i]} + ;; + *) if ((_push_top <= 0)) + then print pushd: Directory stack overflow. + return 1 + fi + esac + case $dir in + \~*) dir=$HOME${dir#\~} + esac + cd "${dir:-$1}" > /dev/null || return 1 + dir=${OLDPWD#$HOME/} + case $dir in + $HOME) + dir=\~ + ;; + /*) ;; + *) dir=\~/$dir + esac + case $type in + 0) # pushd name + _push_stack[_push_top=_push_top-1]=$dir + ;; + 1) # pushd + _push_stack[_push_top]=$dir + ;; + 2) # push +n + type=${1#+} i=_push_top-1 + set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}" + shift $type + for dir + do (((i=i+1) < _push_max)) || break + _push_stack[i]=$dir + done + esac + dirs +} + +# Pops the top directory +function popd +{ + typeset dir + if ((_push_top >= _push_max)) + then print popd: Nothing to pop. + return 1 + fi + case $1 in + "") + dir=${_push_stack[_push_top]} + case $dir in + \~*) dir=$HOME${dir#\~} + esac + cd "$dir" || return 1 + ;; + +[1-9]|+[1-9][0-9]) + typeset savedir + integer i=_push_top$1-1 + if ((i >= _push_max)) + then print pushd: Directory stack not that deep. + return 1 + fi + while ((i > _push_top)) + do _push_stack[i]=${_push_stack[i-1]} + i=i-1 + done + ;; + *) print pushd: Bad directory. + return 1 + esac + unset '_push_stack[_push_top]' + _push_top=_push_top+1 + dirs +} diff --git a/docs/ksh/functions/title.txt b/docs/ksh/functions/title.txt new file mode 100644 index 000000000000..2338ce6b485a --- /dev/null +++ b/docs/ksh/functions/title.txt @@ -0,0 +1,54 @@ +# add to (+), delete from (-), print (.), or set ([=]) window title +# arguments are eval'd before printing +# title text string exported in TITLE_TEXT + +function title # [+ | - | =] title ... +{ + typeset x t="$TITLE_TEXT" + + case $1 in + +) shift + case $# in + 0) ;; + *) for x + do case " $t " in + *" $x "*) ;; + " ") t=$x ;; + *) t="$t $x" ;; + esac + done + case $t in + $TITLE_TEXT) return 1 ;; + esac + ;; + esac + ;; + -) shift + case $# in + 0) ;; + *) for x + do case " $t " in + *" $x "*) t="${t%?( )$x*}${t##*$x?( )}" ;; + esac + done + case $t in + $TITLE_TEXT) return 1 ;; + esac + ;; + esac + ;; + .) print -r -- "$TITLE_TEXT" + return 0 + ;; + *) t="$*" + ;; + esac + export TITLE_TEXT="$t" + eval x=\"$t\" + case $TERM in + 630*) print -nr -- "[?${#x};0v$x" ;; + vt100|xterm*) print -nr -- "]0;$x" ;; + *) return 1 ;; + esac + return 0 +} diff --git a/docs/ksh/functions/vi_keybind.txt b/docs/ksh/functions/vi_keybind.txt new file mode 100644 index 000000000000..56256bfa4571 --- /dev/null +++ b/docs/ksh/functions/vi_keybind.txt @@ -0,0 +1,10 @@ +typeset -A Keytable +trap 'eval "${Keytable[${.sh.edchar}]}"' KEYBD +function vi_keybind +{ + keybind $'\E[A' k # Up key + keybind $'\E[B' j # Down key + keybind $'\E[C' l # Right key + keybind $'\E[D' h # Left key + keybind $'\t' '\' # Tab for command-line completion +} diff --git a/docs/ksh/index.html b/docs/ksh/index.html new file mode 100644 index 000000000000..cf0663d35cc9 --- /dev/null +++ b/docs/ksh/index.html @@ -0,0 +1,10 @@ + +KSH93 + +Overview
+FAQ
+Features
+Builtins
+Examples + + diff --git a/docs/ksh/ksh.html b/docs/ksh/ksh.html new file mode 100644 index 000000000000..8df6639e854b --- /dev/null +++ b/docs/ksh/ksh.html @@ -0,0 +1,118 @@ + + + + + www/ksh/ksh.mm mm document + + + + + +
+ + + +

+

ksh overview

+The +KornShell +language was designed and developed by David G. Korn at AT&T Bell Laboratories and AT&T Research. +It is an interactive command language that provides access to the UNIX system and to many other systems, +on the many different computers and workstations on which it is implemented. +The +KornShell +language is also a complete, powerful, high-level programming language for writing applications, +often more easily and quickly than with other high-level languages. +This makes it especially suitable for prototyping. +There are two other widely used shells, the Bourne shell developed by Steven Bourne at AT&T Bell Laboratories, +and the C shell developed by Bill Joy at the University of California. +ksh +has the best features of both, plus many new features of its own. +Thus +ksh +can do much to enhance your productivity and the quality of your work, +both in interacting with the system, and in programming. +ksh +programs are easier to write, and are more concise and readable than programs written in a lower level language such as C. +

+The new version of +ksh +has the functionality of other scripting languages such as awk, icon, perl, rexx, and tcl. +For this and many other reasons, +ksh +is a much better scripting language than any of the other popular shells. +The code size for +ksh +is larger than the Bourne shell or C shell programs. +The revised version is even larger. +

+In spite of its increased size, +ksh +provides better performance. +You can write programs to run faster with +ksh +than with either the Bourne shell or the C shell, sometimes an order of magnitude faster. +ksh +has evolved and matured with extensive user feedback. +It has been used by many thousands of people at AT&T since 1982, and at many other companies and universities. +A survey conducted at one of the largest AT&T Bell Laboratories computer centers showed that 80% of their customers, both programmers and non-programmers, use +ksh. +ksh +is compatible with the Bourne shell. +Virtually all programs written for the Bourne shell run with +ksh. +If you are familiar with the Bourne shell, you can use +ksh +immediately, without retraining. +The new version of +ksh +is compatible with earlier versions of +ksh. +ksh +is readily available. +It is sold (source and binary) by AT&T and Novell, and by other companies under license from AT&T both in the USA and abroad. +It has been purchased by dozens of major corporations, and by many individuals for use on home computers. +ksh +is extensible. +

+The +KornShell +language uses the same syntax for built-in commands as for non built-in commands. +Therefore, system developers can add new commands "transparently" to the +KornShell +language; that is, with minimum effort and with no differences visible to users other than faster execution. +On systems with dynamic linking, it is possible to add new built-in commands at run time. +Novell has extended the new version of +ksh +to enable X-windows programming for their desktop +ksh +product, +dtksh. +dtksh +is a standard part of CDE, the Common Desktop Environment defined by COSE (Common Operating System Environment), supported by most major UNIX system hardware vendors. +An extended version of +ksh +that enables Tk programming, called tksh, is available as well. +

+ksh +is intended to conform to the Shell Language Standard developed by the IEEE POSIX 1003.2 Shell and Utilities Language Committee. +

+


+ + + + + + +
March 13, 2012
+

+ +

+ + + diff --git a/docs/ksh/scripts/cgi-lib.ksh.txt b/docs/ksh/scripts/cgi-lib.ksh.txt new file mode 100644 index 000000000000..374b79bc65cb --- /dev/null +++ b/docs/ksh/scripts/cgi-lib.ksh.txt @@ -0,0 +1,129 @@ +typeset -A COOKIE HEADER +typeset Cgi _CGI_c _CGI_multipart + +function cgi_header +{ + typeset h + for h in "${!HEADER[@]}" + do printf '%s: %s\n' "$h" "${HEADER[$h]}" + done + print +} + +function cgi_url +{ + if [[ $SERVER_PORT != 80 ]] + then print "http://$SERVER_NAME:$SERVER_PORT$SCRIPT_NAME" + else print "http://$SERVER_NAME$SCRIPT_NAME" + fi +} + +function cgi_parse +{ + if [[ $REQUEST_METHOD == POST ]] + then if [[ $CONTENT_TYPE == multipart/form-data* ]] + then _CGI_multipart=${TMPDIR-/tmp}/cgi-form-$$ + trap 'rm -rf "$_CGI_multipart"' EXIT + mkdir $_CGI_multipart + unset -f Cgi.set + typeset -A Cgi.file + typeset i b v + pax --nosummary --read --edit ",.*/,," --edit ",^,$_CGI_multipart/," + for i in $_CGI_multipart/* + do b=${i##*/} + if [[ $b == +([a-z]) ]] + then v=$(<$i) + eval Cgi.$b='$v' + else Cgi.file[$b]=$i + fi + done + else Cgi=$(<&0) # Read from stdin + fi + else Cgi="$QUERY_STRING" + fi + cgi_cookie "$HTTP_COOKIE" + HEADER["Content-type"]="text/html" +} + +function cgi_cookie +{ + typeset cookie=$1 name val c IFS=';' + set -- $cookie + for c + do + IFS='=' + set -- $c + name=${1##' '} val=${2##' '} # trim white space + name=${name%%' '} val=${val%%' '} + COOKIE[$name]=$val + done +} + +function cgi_setcookie # name value +{ + HEADER["Set-Cookie"]="$1=$2; path=$SCRIPT_NAME" +} + +## Cgi variable disciplines + +function Cgi.set +{ + set -f + typeset i j n val IFS='&' + set -- ${.sh.value} + for i + do n=${i%%=*} + [[ $n == [[:alpha:]_]*([[:alnum:]_]) ]] || continue + val=${i#$n=} + val=${val//+/ } + val=${val//@([\'\\])/'\'\1} + eval j=\${#${.sh.name}.${n}[@]} \ + "${.sh.name}.${n}[j]=\$'${val//'%'@(??)/'\x'\1"'\$'"}'" + done +} + +function cgi_C_init +{ + integer i + for ((i=1; i < 256; i++)) + do if (( i!=16#22 && i!=16#27 && i!=16#5C && i!=16#5B && i!=16#5D )) + then printf $'_CGI_c[$\'\\\\x%.2X\']=%%%.2X\n' $i $i + fi + done + print +} + +function cgi_encode +{ + typeset v=$1 + var=${v//' '/+} + cbrace='}' + eval var=${var//@([!a-zA-Z0-9_+])/\${_CGI_c[\\\1]$cbrace} + print -r -- "$var" +} + +function Cgi.get +{ + typeset i val name vname + if [[ ! ${_CGI_c[\\]} ]] + then val='"' + _CGI_c[""]=%00 + _CGI_c[$var]=%22 + _CGI_c[\']=%27 + _CGI_c[\]]=%5B + _CGI_c[\[]=%5D + _CGI_c[\\]=%5C + eval $(cgi_C_init) + unset -f cgi_C_init + fi + vname=${.sh.name} # .sh.name contains variable name + .sh.value= # .sh.value stores value + for i in ${!Cgi.@} + do + name=${i#$vname.} + nameref v=${i} + val=$(cgi_encode "$v") + .sh.value="${.sh.value}${.sh.value:+&}$name=$val" + done +} + diff --git a/docs/ksh/scripts/dump-cgi.ksh.txt b/docs/ksh/scripts/dump-cgi.ksh.txt new file mode 100644 index 000000000000..57992162601e --- /dev/null +++ b/docs/ksh/scripts/dump-cgi.ksh.txt @@ -0,0 +1,17 @@ +#!/bin/ksh + +. ./cgi-lib.ksh + +cgi_parse +cgi_header + +print "" +print "
"
+print -r "Url: $(cgi_url)"
+for i in ${!Cgi.*}
+do
+	nameref val=$i
+	print -r "$i = $val"
+done
+print "
" +print "" diff --git a/docs/ksh/scripts/env.txt b/docs/ksh/scripts/env.txt new file mode 100644 index 000000000000..5989dd7e4954 --- /dev/null +++ b/docs/ksh/scripts/env.txt @@ -0,0 +1,66 @@ +#! /usr/bin/ksh +# shell version of env command +case $(getopts '[-]' opt '--???man' 2>&1) in +version=[0-9]*) + usage=$'[-?@(#)env (AT&T Labs Research) 1999-05-20\n] + [-author?David Korn ] + [-license?http://www.research.att.com/sw/tools/reuse] + [+NAME?env - set environment for command invocation] + [+DESCRIPTION?\benv\b modifies the current environment according + to the \aname\a\b=\b\avalue\a arguments, and then + invokes \acommand\a with the modified environment.] + [+?If \acommand\a is not specified, the resulting environment + is written to standard output quoted as required for + reading by the \bsh\b.] + [i:ignore-environment?Invoke \acommand\a with the exact environment + specified by the \aname\a\b=\b\avalue\a arguments; inherited + environment variables are ignored. As an obsolete feature, + \b-\b by itself can be specified instead of \b-i\b.] + [u:unset]:[name?Unset the environment variable \aname\a if it was + in the environment. This option can be repeated to unset + additional variables.] + + [name=value]... [command ...] + + [+EXIT STATUS?If \acommand\a is invoked, the exit status of \benv\b + will be that of \acommand\a. Otherwise, it will be one of + the following:]{ + [+0?\benv\b completed successfully.] + [+126?\acommand\a was found but could not be invoked.] + [+127?\acommand\a could not be found.] + } + [+SEE ALSO?\bsh\b(1), \bexport\b(1)] + ' + ;; +*) + usage='iu:[name] [name=value]... [command ...]' + ;; +esac +clear= +while getopts "$usage" var +do case $var in + i) clear=1;; + u) command unset $OPTARG 2> /dev/null;; + esac +done +#[[ $var == "" ]] || exit 1 +shift $((OPTIND-1)) +if [[ $1 == - ]] # obsolete form +then clear=1 + shift +fi +if [[ $clear == 1 ]] +then typeset +x $(typeset +x) +fi +while true +do case $1 in + *=*) export "$1";; + *) break;; + esac + shift +done +if (( $# >0 )) +then exec "$@" +else export + exit 0 +fi diff --git a/docs/ksh/scripts/line.txt b/docs/ksh/scripts/line.txt new file mode 100644 index 000000000000..7451ea51a403 --- /dev/null +++ b/docs/ksh/scripts/line.txt @@ -0,0 +1,2 @@ +#! /bin/ksh +read -r && print -r -- "$REPLY" diff --git a/docs/ksh/scripts/which.txt b/docs/ksh/scripts/which.txt new file mode 100644 index 000000000000..1e4b009cbb08 --- /dev/null +++ b/docs/ksh/scripts/which.txt @@ -0,0 +1,2 @@ +#! /bin/ksh +whence -p "$@"