1.nr N 2 2.PF "'Copyright (c) 1984, 1985, 1986, 1987''AT&T All Rights Reserved'" 3.SA 1 \" right justified 4.TL "311531-0101" "49059-6" \" charging case filing case 5Introduction to KSH-I ( Issue 3) 6.AU "David G. Korn" DGK MH 59554 7975 5D-112 "(ulysses!dgk)" 7.TM 59554-860602-04 \" technical memo + TM numbers 8.AS 1 \" abstract start for TM 9Ksh-i is a command language (shell) for the UNIX*\ 10.FS * 11UNIX is a trademark of Bell Laboratories. 12.FE 13operating system. 14It is essentially compatible with the System V version of the Bourne shell\*(Rf , 15.RS 16S. R. Bourne, 17.I "An Introduction to the UNIX 18Shell," 19BSTJ - Vol. 57, No. 6 part 2, pages 1947-1972. 20.RF 21has many additional features, 22such as those found in 23.IR Csh\*(Rf , 24.RS 25W. Joy, 26.I "An Introduction to the C Shell," 27University of California, Berkeley, 1980. 28.RF 29and executes faster than either of these shells. 30This memo introduces many of the additional features 31and explains some of the reasons for the better 32performance. 33This memo 34assumes that the reader is already familiar with the Bourne shell. 35The Appendix contains 36a sample script written in Ksh-i. 37The manual page for the current version is also included. 38.AE \" abstract end 39.OK Shell "Command interpreter" Language UNIX \" keyword 40.MT 1 \" memo type 41.H 1 "Introduction" 42.P 43Over the past several years several papers 44have been written describing new command interpreters 45for the UNIX system. 46These papers can be divided into two categories: 47Those that improve the shell as a programming language, 48and those that improve the shell as a command interpreter. 49Most of the papers fall into the latter category. 50In particular, 51.IR vicmd \*(Rf 52.RS 53S. L. Arnold, 54.I "Vicmd a Visual Shell for Video Terminals," 55TM-81-54533-12, 1981. 56.RF 57preserves the friendly environment of 58.I vi 59(from which this memo was entered), 60and adds a facility for convenient command entry. 61An 62.I emacs 63oriented shell 64has also been written by Veach\*(Rf. 65.RS 66J. L. Steffen and 67M. T. Veach, 68.I "The Edit Shell - Connecting Screen Editing with the History List," 69USENIX Association Toronto Proceedings, 1983. 70.RF 71The 72.IR 2dsh \*(Rf 73.RS 74M. J. Rochkind, 75.I "2dsh - An Experimental Shell for Connecting Processes With Multiple Data Streams," 76TM-80-9323-3. 77.RF 78shell allows the setup of more complicated networks of processes than 79just pipelines. 80The never developed 81.IR See-shell \*(Rf 82.RS 83Wayne T. Wilner, 84.I "See-Shell: a Graphical User-Interface for UNIX Systems," 85Bell Laboratories internal memorandum, 1982. 86.RF 87proposes a Small-Talk like interface\*(Rf 88.RS 89D. C. Smith, C. Irby, R. Kimball, and B. Verplank, 90.I "Designing the Star User Interface," 91BYTE, April, 1982, pp. 242-282. 92.RF 93suitable for bit-mapped terminals such as the BLIT\*(Rf 94.RS 95R. Pike, 96.I "The Blit Programmer's manual," 97Bell Labs, 1982. 98.RF 99and the Apollo\*(Rf. 100.RS 101P. J. Leach, 102P. H. Levine, 103B. P. Douros, 104J. A. Hamilton, 105D. L. Nelson, 106and B. L. Stumfp, 107.I "The Architecture of an Integrated Local Network," 108IEEE Journal of Selected Areas in Communications, 109Local Area Networks Special Issue, November 1983. 110.RF 111Perhaps the most widely used shell, 112other than the Bourne shell, is 113.IR Csh , 114which runs under the Berkeley UNIX operating system. 115Csh has many attractive command interpreter features 116not currently in the Bourne shell; 117most notably, job control, 118history, 119arithmetic, 120and command name aliasing. 121On the other hand, 122many people (including this author), 123think that the Bourne shell is superior as a programming language. 124The history mechanism of Csh has recently been added as a local modification 125to the Bourne shell by 126J. L. Steffen\*(Rf. 127.RS 128J. L. Steffen, 129.I "An Input History for the Bourne Shell," 130TM-82-55426-3, 1982. 131.RF 132.P 133The use of the shell as a programming language has been 134described by Dolotta and Mashey\*(Rf 135.RS 136T. A. Dolotta and J. R. Mashey, 137.I "Using the shell as a Primary Programming Tool," 138Proc. 2nd. Int. Conf. on Software Engineering, 1976, 139pages 169-176. 140.RF 141and has been used by many people here 142at Bell Laboratories. 143Kolettis\*(Rf 144.RS 145N. J. Kolettis. 146.I "Extended Shell - A Potential Real Time Interpreter," 147TM-77-4145-01, 1977. 148.RF 149presented extensions to the Bourne shell to provide 150message passing facilities and other inter-process communication and 151synchronization features. 152The Form shell\*(Rf 153.RS 154D. G. Korn and D. A. Lambeth, 155.I "Form Shell," 156TM-80-9224-3, 1980. 157.RF 158added form entry/edit capabilities to the Bourne shell. 159A proposal for a more programming language oriented shell has 160been proposed by Sturzenbecker\*(Rf. 161.RS 162M. C. Sturzenbecker, 163.I "A New Command Language for UNIX and related systems," 164TM-82-45192-3. 165.RF 166.P 167This memo describes 168.IR Ksh-i , 169aka Korn shell-international. 170This memo is not a tutorial, only an introduction. 171A description of the 172.IR Korn shell 173can be found in Kochan and Wood\*(Rf. 174.RS 175S. G. Kochan and P. H. Wood, 176"Unix Shell Programming," 177Hayden Book Company, 1985. 178.RF 179Ksh-i is a direct descendant of the 180Form shell 181with most of the 182form entry/edit features removed and with many new 183features added. 184The primary focus of this work has been to provide an 185enhanced programming environment in addition 186to the major command entry features of 187.IR Csh . 188Improved performance has been a major objective. 189Many of the additions have been provided so that 190medium sized programming tasks can be written 191at the shell level without a serious performance 192penalty. 193A concerted effort has been made to achieve System V Bourne shell 194compatibility so that scripts written for the Bourne shell 195can run without modification with Ksh-i. 196The description of features in this memo assumes 197that the reader is already familiar with the Bourne shell. 198.P 199A version of Ksh-i has been run on several machines 200including but not limited to VAXEN , PDP-11's, IBM-370's, 201AT&T 3B's, UNIX-PC, PC-6300+, Suns, Alliant, CCI, Sequent, 202Pyramid, and Apollo Domain. 203It has been run on top of several versions of the UNIX operating system including 204Venix, Xenix, System III, System V, UTS, 205BSD 4.1, 4.2, 4.3, 8th. Edition, and DOMAIN/IX. 206The shell is in use in several centers at AT&T Bell Laboratories, 207and has been installed as 208.I /bin/sh 209on VAXEN running System V, BSD 4.1., BSD 4.2, 2103B's, PC-6300+, and UNIX-PC's running System V. 211.H 1 "Shell Variables" 212.P 213The ability to define and use variables to store and retrieve values 214is an important feature in most programming languages. 215Ksh-i has variables with 216.I identifier 217names that follow the 218same rules as the Bourne shell. 219Since all variables have string representations, 220there is no need to specify the 221.I type 222of each variable in the shell. 223In Ksh-i, 224each variable can have one or more 225.I attributes 226that control the internal representation of the variable, 227the way the variable is printed, and its access or 228scope. 229Two of the attributes, 230.I readonly 231and 232.IR export , 233are available in the Bourne shell. 234The 235.B typeset 236built-in command of Ksh-i 237assigns attributes to variables. 238The complete list of attributes, 239some of which are discussed here, 240appears in the manual page. 241The 242.B unset 243built-in of the Ksh-i removes 244values and attributes of parameters. 245.P 246Whenever a value is assigned to a variable, 247the value is transformed according to the attributes of the variable. 248Changing the attribute of a variable can change its value. 249There are three attributes for field justification, 250as might be needed for formatting a report. 251For each of these attributes, a width can be defined explicitly or else 252it is defined the first time an assignment is made to the variable it 253Each assignment causes justification of the field, truncating 254if necessary. 255Assignment to fixed sized variables 256provides a simple way to generate a substring consisting of 257a fixed number of characters from 258the beginning or end of a string. 259.P 260The attributes 261.B \-u 262and 263.BR \-l , 264are used for upper case and lower case 265formatting respectively. 266Since it makes no sense to have both attributes on simultaneously, 267turning on either of these attributes turns the other off. 268The following script provides an example of the use of shell variables 269with attributes. 270This script reads a file of lines each consisting of five fields separated by 271.B : 272and prints fields 4 and 2 in upper case in columns 1-15, left justified, 273and columns 20-25 right-justified respectively. 274.sp 275.nf 276.in .5i 277.ta 3.4i 278.B 279typeset \-L15u f4 # 15 character left justified 280typeset \-R6u f2 # 6 character right justified 281IFS=: 282set \-f # skip file name generation 283while read \-r f1 f2 f3 f4 f5 # read line, split into fields 284do print \-r "$f4 $f2" # print fields 4 and 2 285done 286.fi 287.ta 288.in 289.sp 290.R 291.P 292The integer attribute, 293.BR \-i , 294causes the variable to be internally represented as an integer. 295The 296.B i 297can be followed by a number representing the numeric base for printing, otherwise 298the first assignment to an 299.I integer 300variable defines the output 301.I base 302(see below). 303This base will be used 304whenever the variable is printed. 305Assignment to 306.I integer 307typed variables result in arithmetic evaluation, 308as described below, 309of the right hand side. 310.P 311Ksh-i allows one-dimensional 312.I arrays 313in addition to simple variables. 314Any variable can become an array 315by referring to it with 316a 317.IR subscript . 318All elements of an array need not exist. 319Subscripts for arrays 320must evaluate to an 321integer between 0 and 511, otherwise 322an error results. 323Evaluation of subscripts is described in 324the next section. 325Attributes apply to the whole array. 326.P 327Assignments to array variables can be made with parameter assignment statements 328or with the 329.B typeset 330built-in. 331Referencing of subscripted variables requires the character 332.BR $ , 333but also requires braces around the array element name. 334The braces are needed to avoid conflicts with the 335file name generation mechanism. 336The form of any array element reference is: 337.ce 338.BI ${ name [ subscript ]} . 339A subscript value of 340.B * 341or 342.B @ 343can be used to generate all elements of an array, 344as they are used for expansion of positional parameters. 345.P 346A few additional operations are available on shell variables. 347\f3${#\fP\f2name\fP\f3}\fP 348will be the length in bytes of 349\f3$\fP\f2name\fP. 350For an array variable 351\f3${#\fP\f2name\fP\f3[*]}\fP 352gives the number of elements in the array. 353.P 354There are four parameter substitution modifiers that 355have been added to strip off leading and trailing substrings 356during parameter substitution. 357The modifier 358.BR # ( ## ) 359strips off the smallest (largest) matching pattern from the left 360and the modifier 361.BR % ( %% ) 362strips off the smallest (largest) matching pattern from the right. 363For example, if the shell variable 364.B i 365has value 366.BR file.c , 367then the expression 368.B ${i%.c}.o 369has value 370.BR file.o . 371.H 1 "Arithmetic Evaluation" 372.P 373The built-in command, 374.B let , 375provides the ability to do integer arithmetic. 376All arithmetic evaluations are performed using 377.I long 378arithmetic. 379Arithmetic constants are written as 380.br 381.ce 382.IB base # number 383where 384.I base 385is a decimal integer between 386two and thirty-six and 387.I number 388is any non-negative number. 389Anything after a decimal point is truncated. 390Base ten is used 391if no base is specified. 392.P 393Arithmetic expressions are made from constants, 394variables, and one or more of the fourteen operators 395listed in the manual page. 396Operators are evaluated in order of precedence. 397Parentheses may be used for grouping. 398A variable does not have to have an integer attribute 399to be used within an arithmetic expression. 400The name of the variable is replaced 401by its value within an arithmetic 402expression. 403The statement 404.ce 405.B 406let x=x+1 407.R 408can be used to 409increment a variable 410.BR x . 411Note that there is no space before or after the operators 412.B + 413and 414.BR = . 415This is because each argument to 416.B let 417is an expression to evaluate. 418The last expression determines 419the value returned by 420.BR let . 421Let returns true 422if the last expression evaluates to a non-zero value. 423Otherwise, 424.B let 425returns false. 426.P 427Many of the arithmetic operators have special meaning 428to the shell and must be quoted. 429Since this can be burdensome, an alternate form of arithmetic 430evaluation syntax has been provided. 431For any command that begins with 432.BR (( , 433all the characters until the matching 434.B )) 435are treated as a quoted arithmetic expression. 436The double parentheses 437usually avoids incompatibility with the Bourne shell's use of 438parentheses for grouping a set of commands 439to be run in a sub-shell. 440Expressions inside double parentheses can contain blanks 441and special characters without quoting. 442More precisely, 443.ce 444.B 445(( ... )) 446.R 447is equivalent to 448.ce 449.B 450let " ... " 451.R 452.P 453The following script prints the first 454.I n 455lines of its standard input onto its standard output, 456where 457.I n 458can be supplied as an optional argument whose default value is 20. 459.B 460.sp 461.nf 462.in .5i 463.ta 4i 464typeset \-i n=${1-20} # set n 465while read \-r line && (( (n=n\-1)>=0 )) # at most n lines 466do print \-r \- "$line" 467done 468.fi 469.ta 470.in 471.sp 472.R 473.H 1 "Functions and Command Aliasing" 474.P 475Two new mechanisms have been provided for creating 476pseudo-commands, i. e., 477things that look like commands, 478but do not always create a process. 479The first technique is called command name 480.IR aliasing . 481.P 482As a command is being read, 483the command name is checked against a list of 484.I alias 485names. 486If it is found, 487the name is replaced by the text associated with the 488.I alias 489and then rescanned. 490The text of an alias is not checked for aliases 491so recursive definitions are not allowed. 492However, if the value of an alias ends in a space, 493then the word following the alias is also checked for alias substitution. 494.P 495Aliases are defined with the 496.B alias 497built-in. 498The form of an 499.B alias 500command definition is: 501.ce 502.BI "alias " name = value 503The first character of an 504.I alias 505name can be any non-special printable character, while all remaining characters 506must be alpha-numeric. 507The replacement text, 508.I value, 509can contain any valid shell script, 510including meta-characters such as pipe symbols and i/o-redirection. 511Unlike 512.BR csh , 513aliases in 514.B Ksh-i 515cannot take arguments. 516Aliases can be used to redefine built-in commands so that 517the alias 518.ce 519.B "alias test=./test" 520can be used to look for 521.I test 522in your current working directory rather than 523using the built-in 524.B test 525command. 526Keywords such as 527.B for 528and 529.B while 530cannot be changed by aliasing. 531The command 532.BR alias , 533without arguments, generates 534a list of aliases and corresponding texts. 535The 536.B unalias 537command removes the name and text of an alias. 538.P 539Aliases are used to save typing and to improve readability of scripts. 540For example, the alias 541.B 542alias integer=\(fmtypeset \-i\(fm 543.R 544allows integer the variables 545.B i 546and 547.B j 548to be declared and initialized with the command 549.BR "integer i=0 j=1" . 550.P 551Aliases can be used to bind program names to the 552full path-name of the program. This eliminates the path search 553but requires knowledge of where that program will be stored. 554.I Tracked 555aliases 556make this use for aliasing automatic. 557A tracked alias is not given a value. Its value is 558defined at the first 559reference by a path-search as the full path-name equivalent of the name, and 560remains defined until the 561.B PATH 562variable is changed. 563Programs found in directories that do not begin with 564.B / 565that occur earlier in the path-search than the value of the 566tracked alias, take precedence over tracked aliases. 567.P 568Tracked aliases provide an alternative to the 569.I Csh 570command hashing facility. Tracked aliases do not require time for 571initialization and allow for new commands to be introduced 572without the need for re-hashing. 573The 574.B \-h 575option to the shell allows all command names that are 576valid alias names to become tracked aliases. 577This option is automatically turned on for non-interactive shells. 578.P 579.I Functions 580are more general than aliases but also more costly. 581Functions definitions are of the form 582.sp 583.in +.5i 584.BI "function " name 585.br 586.B { 587.br 588 any shell script 589.br 590.B } 591.sp 592.in 593The function is invoked by writing 594.I name 595and optionally following it with arguments. 596Positional parameters are saved before each 597function call and restored when completed. 598Functions are executed in the current shell environment 599and can share named variables with the calling program. 600Options, other than execution trace 601.BR \-x , 602set by the calling program are 603passed down to a function. 604The option flags are 605not shared with 606the function so that any options set within a function are 607restored when the function exits. 608All traps other than 609.B EXIT 610and 611.B ERR 612(described later) 613are also inherited. 614A trap on 615.B EXIT 616within a function will execute after the function completes but 617before the caller resumes. 618Therefore, 619any variable assignments and 620any options set as part of a trap action will be effective 621after the caller resumes. 622The 623.B return 624built-in can be used to cause the function to return to 625the statement following 626the point of invocation. 627.P 628By default, variables are inherited by the function and shared 629by the calling program. 630However, 631environment substitutions preceding the function call 632apply only to the scope of the function call. 633Also, variables defined with the 634.BR typeset , 635built-in command are local to the function that they are declared in. 636Thus, for the function defined 637.B 638.sp 639.nf 640.in .5i 641function name 642{ 643 typeset \-i x=10 644 let z=x+y 645 print $z 646} 647.fi 648.ta 649.in 650.sp 651.R 652invoked as 653.BR "y=13 name" , 654.B x 655and 656.B y 657are local variables with respect to the function 658.B name 659while 660.B z 661is global. 662.P 663Alias and function names are never directly carried across separate 664invocations of Ksh-i, but can be passed down to sub-shells. 665Ordinarily, shell scripts invoked by name are executed in a sub-shell while 666scripts invoked as 667.B ksh 668.I script 669and shell escapes from other programs 670are carried out by a separate shell invocation. 671The 672.B \-x 673flag is used with 674.B alias 675to carry aliases to sub-shells while the 676.B \-fx 677flags of 678.B typeset 679are used to do the same for functions. 680.P 681Each user can create a startup file for aliases and functions or 682any other commands. 683Aliases and functions that are to be available for all shell invocations 684should be put into this file. 685Aliases and functions which should apply to 686scripts, as well as interactive use, should be set with the 687.B \-x 688flag. 689Setting this flag to redefine the semantics of a command 690can have undesired side effects. 691For example, 692.B "alias \-x ls='ls \-l'" 693will cause shell procedures which use the 694.B ls 695command within a pipeline to break. 696By setting and exporting the environment variable, 697.BR ENV , 698to the name of this file, 699the aliases and functions will be defined each time Ksh-i 700is invoked. 701The value of the 702.B ENV 703variable undergoes parameter substitution prior to its use. 704.P 705Several of the UNIX commands can be aliased to Ksh-i built-ins. 706Some of these are automatically set each time the shell is invoked. 707In addition, 708about twenty frequently used UNIX commands are set as tracked aliases. 709.P 710The location of an alias command can be important 711since aliases are only processed when a command is read. 712A 713.B . 714procedure is read all at once (unlike 715.I profiles 716which are read a command at 717a time) so that any aliases defined there will not effect any commands 718within this script. 719.P 720A name is checked to see if it is a built-in command before checking to see 721if it is a function. To write a function to replace a built-in command 722you must define a function with a different name and alias the 723built-in name to this function. 724For example to write a 725.B cd 726function which changes the directory and prints out the directory name, 727you can write, 728.B 729.sp 730.nf 731.in .5i 732alias cd=_cd 733function _cd 734{ 735 if 'cd' "$@" 736 then echo $PWD 737 fi 738} 739.fi 740.ta 741.in 742.sp 743.R 744The single quotes around 745.B cd 746within the function prevents alias substitution. 747The 748.B PWD 749variable is described below. 750.P 751The combination of aliases and functions can be used 752to do things that can't be done with either of these 753separately. For example, the function and aliases 754defined as 755.B 756.sp 757.nf 758.in .5i 759function _from # i=start to finish [ by incr] 760{ 761 typeset var=${1%%=*} 762 integer incr=${5\-1} $1 763 while (( $var <= $3 )) 764 do _repeat 765 let $var=$var+incr 766 done 767} 768alias repeat='function _repeat {' from='}; _from' 769.fi 770.ta 771.in 772.sp 773.R 774allow you to write loops such as 775.B 776.sp 777.nf 778.in .5i 779repeat 780 any script command 781from i=1 to 13 by 3 782.fi 783.ta 784.in 785.sp 786.R 787with the expected behavior. 788.H 1 "Input and Output" 789.P 790An extended I/O capability has been added 791to enhance the 792use of the shell as a programming language. 793The Bourne shell has a built-in 794.B read 795for reading lines from file descriptor 0, 796but does not have any internal output mechanism. 797As a result, the 798.B echo(1) 799command has been used to produce output for a shell procedure. 800This is inefficient and also restrictive. 801For example, there is no way to read in a line 802from a terminal and to 803.I echo 804the line exactly as is. 805In the Bourne shell, 806the 807.B read 808built-in cannot be used to read lines that end in 809.BR `\e' , 810and the 811.B echo 812command will treat certain sequences as control sequences. 813In addition, 814there is no way to have more than one file open 815at any time for reading. 816.P 817Ksh-i has options on the 818.B read 819command to specify the file 820descriptor for the input. 821The 822.B exec 823built-in can be used to open, close, and duplicate file streams. 824The 825.B \-r 826option allows a 827.B `\e' 828at the end of an input line to be treated as a regular 829character rather than the line continuation character. 830The first argument of the 831.B read 832command can be followed by a 833.B ? 834and a prompt to produce a prompt at the 835terminal before the read. 836If the input is not from a terminal device then 837the prompt is not issued. 838.P 839The Ksh-i built-in, 840.BR print , 841is used to output characters to the terminal or to a file. 842Again, it is possible to specify the file descriptor number 843as an option to the command. 844Ordinarily, the arguments to this command are processed 845the same as for 846.BR echo(1) . 847However, the 848.B \-r 849flag can be used to output the arguments without any special meaning. 850The 851.B \-n 852flag can be used here to suppress the trailing new-line 853that is ordinarily appended. 854.P 855To improve performance of existing shell programs, 856the 857.B echo 858command is built into Ksh-i. 859For the System V version of Ksh-i, the built-in 860.B echo 861is equivalent 862.ce 863\f3print \-\fR, 864where the 865.B \- 866signifies that there are no more options permitted. 867On the Berkeley UNIX version the value of the 868.B PATH 869variable determines the behavior of the built-in 870.B echo 871command. 872If 873.B echo 874would resolve to 875.B /bin/echo 876with a path search, then 877.B echo 878is equivalent to 879.ce 880\f3print \-R\fR. 881The 882.B \-R 883option allows only the 884.B \-n 885flag to be recognized as the next argument. 886Otherwise, 887.B echo 888behaves like the System V 889.B echo 890command. 891.P 892The shell is frequently used as a programming language for 893interactive dialogues. 894The 895.B select 896statement has been added to the language 897to make it easier to 898present menu selection alternatives to the 899user and evaluate the reply. 900The list of alternatives is numbered and put in columns. 901A user settable prompt, 902.BR PS3 , 903is issued and if the answer is 904a number corresponding to one of the alternatives, 905the select loop variable is set to this value. 906In any case, the 907.B REPLY 908variable is used to store the user entered reply. 909The shell variables 910.B LINES 911and 912.B COLUMNS 913are used to control the layout of select lists. 914.H 1 "Command Re-entry" 915.P 916An interactive shell saves the 917commands you type at a terminal in a file. 918If the variable 919.B HISTFILE 920is set to the name of a file to which the user 921has write access, 922then the commands are stored in this 923.I history 924file. 925Otherwise the file 926.B $HOME/.sh_history 927is checked for write access and if this fails 928an unnamed file is used to hold the history lines. 929This file may be truncated if this is a top level shell. 930The number of commands accessible to the user, is determined by the value of the 931.B HISTSIZE 932variable at the time the shell is invoked. 933The default value is 128. 934A command may consist of one or more lines since a compound 935command is considered one command. 936If the character 937.B ! 938is placed within the 939.I "primary prompt" 940string, 941.BR PS1 , 942then it is replaced by the command number each time the prompt is given. 943Whenever the history file is named, 944all shells which use this file share access to the same history. 945.P 946A built-in command 947.B fc 948(fix command) is used to list and/or edit 949any of these saved commands. 950The command can always be specified with 951a range of one or more commands. 952The range can be specified by giving the command 953number, relative or absolute, or by giving 954the first character or characters of the command. 955The option 956.B \-l 957is used to specify listing of previous commands. 958When given without specifying the range, 959the last 16 960commands are listed, each 961preceded by the command number. 962.P 963If the listing option is not selected, 964then the range of commands specified, 965or the last command if no range is given, 966is passed to an editor program before 967being re-executed by Ksh-i. 968The editor to be used may be specified 969with the option 970.B \-e 971and following it with the editor name. 972If this option is not specified, the 973value of the shell variable 974.B FCEDIT 975is used as the name of the editor, 976providing that this variable has non-null value. 977If this variable is not set, or is null, 978and the 979.B \-e 980option has not been selected, 981then 982.B /bin/ed 983is used. 984When editing has been complete, 985the edited text automatically becomes 986the input for Ksh-i. 987As this text is read by Ksh-i, it is echoed onto the terminal. 988.P 989An editor name of 990.B \- 991is used to bypass the editing and just re-execute the command. 992In this case only a single command can be specified as the range 993and an optional argument of the form 994\f2old\fP\f3=\fP\f2new\fP 995may be added which requests a simple string substitution 996prior to evaluation. 997A convenient alias, 998.ce 999.B 1000alias r=\(fmfc \-e \-\(fm 1001.R 1002has been pre-defined so that 1003the single key-stroke 1004.B r 1005can be used to re-execute the previous command 1006and the key-stroke sequence, 1007.B 1008r abc=def c 1009.R 1010can be used to re-execute the last command that starts with 1011the letter 1012.B c 1013with the first occurrence of the string 1014.B abc 1015replaced with the string 1016.BR def . 1017Typing 1018.B 1019r c > file 1020.R 1021re-executes the most recent command starting with the letter 1022.BR c , 1023with standard output redirected to 1024.IR file . 1025.H 1 "In-line editing" 1026.P 1027Lines typed from a terminal frequently need changes made 1028before entering them. 1029With the Bourne shell the only method to fix up commands 1030is by backspacing or killing the whole line. 1031Ksh-i offers options that allow the user to edit parts of the 1032current command line before submitting the command. 1033The in-line edit options make the command line into a single 1034line screen edit window. 1035When the command is longer than the width of the terminal, 1036only a portion of the command is visible. 1037Moving within the line automatically makes that portion visible. 1038Editing can be performed on this window until the 1039.I return 1040key is pressed. 1041The editing modes have commands that access the history file 1042in which previous commands are saved. 1043A user can copy any of the most recent 1044.B HISTSIZE 1045commands from this file into the input edit window. 1046You can locate commands by searching or by position. 1047.P 1048The in-line editing options do not use the 1049.I termcap 1050database. 1051They work on most standard terminals. 1052They only require that the backspace character moves the cursor left 1053and the space character overwrites the current character on the screen 1054and moves the cursor to the right. 1055.P 1056There is a choice of editor options. 1057The 1058.IR emacs , 1059.IR gmacs , 1060or 1061.I vi 1062option is selected by turning on the 1063corresponding 1064option of the 1065.B set 1066command. 1067If the value of the 1068.B EDITOR 1069or 1070.B VISUAL 1071ends any of these suffixes 1072the corresponding options is turned on. 1073A large subset of each of each of these editors' 1074features are available within the shell. Additional 1075functions, such as file name completion, have also been added. 1076.P 1077The code for the 1078.I emacs 1079and 1080.I gmacs 1081editing option was supplied by Mike Veach. 1082In the 1083.I emacs 1084or 1085.I gmacs 1086mode the user positions the cursor to the point 1087needing correction and inserts, deletes, or replaces 1088characters as needed. 1089The only difference between these two modes is the 1090meaning of the command 1091.BR ^T . 1092Control keys and escape sequences are used for cursor 1093positioning and control functions. 1094The available editing functions are listed in the manual page. 1095.P 1096The code for the 1097.I vi 1098editing option was supplied by Pat Sullivan. 1099The 1100.I vi 1101editing mode 1102starts in insert mode and enters control mode when the 1103user types 1104.BR ESC ( 1105.BR 033 ). 1106The 1107.I return 1108key, which submits the current command for processing, 1109can be entered from either mode. 1110The cursor can be anywhere on the line. 1111A subset of commonly used 1112.I vi 1113commands are available. 1114The 1115.B k 1116and 1117.B j 1118command that normally move up and down by one 1119.IR line , 1120move up and down one 1121.I command 1122in the history file, 1123copying the command into the input edit window. 1124For reasons of efficiency, 1125the terminal is kept in canonical mode until an 1126.B ESC 1127is typed. 1128On some terminals, 1129and on earlier versions of the UNIX operating system, 1130this doesn't work correctly. 1131The 1132.B viraw 1133option 1134of the 1135.B set 1136command, which always uses 1137.B raw 1138or 1139.B cbreak 1140mode, 1141must be used in this case. 1142.P 1143Most of the code for the editing options does not rely on the 1144Ksh-i code and be used in a stand-alone mode with most any command 1145to add in-line edit capability. 1146However, 1147all versions of the in-line editors have some features that 1148use some shell specific code. For example, 1149.B ESC-= 1150in all edit modes prints the names of files that match the current 1151word and 1152.B ESC-* 1153adds the expanded list of matching files to the command line. 1154A trailing 1155.B * 1156is added to the word if it doesn't contain any file pattern matching 1157characters before the expansion. 1158.H 1 "Job Control" 1159.P 1160The job control mechanism 1161is almost identical to the version found in 1162.I Csh 1163of the Berkeley UNIX operating system, 1164version 4.1. 1165The job control feature allows the user to stop and 1166restart programs, and to move programs to and from the 1167foreground and the background. 1168It will only work on systems that provide support for 1169these features. 1170However, 1171even systems without job control have a 1172.B monitor 1173option which when enabled will report the progress 1174of background jobs and enable the user to 1175.B kill 1176jobs by job number or job name. 1177.P 1178An interactive shell associates a 1179.I job 1180with each pipeline typed in from the terminal 1181and assigns them a small integer number 1182called the job number. 1183If the job is run asynchronously, 1184the job number is printed at the terminal. 1185At any given time, only one job owns the terminal, 1186i. e., keyboard signals are only sent to the processes in one job. 1187When Ksh-i creates a foreground job, 1188it gives it ownership of the terminal. 1189If you are running a job and wish to stop 1190it you hit the key 1191.B ^Z 1192(control-Z) 1193which sends a 1194.B STOP 1195signal to all processes in the current job. 1196The shell receives notification that the processes 1197have stopped and takes back control of the terminal. 1198.P 1199There are commands to continue programs in the foreground 1200and background. 1201There are several ways to refer to jobs. 1202The character 1203.B % 1204introduces a job name. 1205You can refer to jobs by name or number as described in the manual page. 1206The built-in command 1207.B bg 1208allows you to continue a job in the background, 1209while the built-in command 1210.B fg 1211allows you to continue a job in the foreground even 1212though you may have started it in the background. 1213.P 1214A job being run in the background will stop if it tries 1215to read from the terminal. 1216It is also possible to stop background jobs that try to write on 1217the terminal by setting the terminal options 1218appropriately. 1219.P 1220There is a built-in command 1221.B jobs 1222that lists the status of all running and stopped jobs. 1223In addition, 1224you are notified of the change of state of any background 1225jobs just before each prompt. 1226When you try to leave the shell while jobs are stopped or running, 1227you will receive a message from Ksh-i. 1228If you ignore this message and try to leave again, 1229all stopped processes will be terminated. 1230.P 1231A built-in version of 1232.B kill 1233makes it possible to use 1234.I job 1235numbers as targets for signals. 1236Signals can be selected by number or name. 1237The name of the signal is the name found in the 1238.I include 1239file 1240.B /usr/include/signal.h 1241with the prefix 1242.B SIG 1243removed. 1244The 1245.B \-l 1246flag of 1247.B kill 1248generates list of valid signal numbers and names. 1249.H 1 Security 1250There are several documented problems associated with the security of 1251shell procedures\*(Rf. 1252.RS 1253F. T. Grampp and R. H. Morris, 1254.I "UNIX Operating System Security," 1255AT&T Bell Labs Tech. Journal, Vol. 63, No. 8, Part 2, pp.1649-1671, 1984. 1256.RF 1257These security holes occur primarily because a user can manipulate the 1258.I environment 1259to subvert the intent of a 1260.I setuid 1261shell procedure. 1262Frequently, shell procedures are initiated from 1263binary programs, without the author's 1264awareness, by library routines which invoke shells to carry out 1265their tasks. 1266When the binary program is run 1267.I setuid 1268then the shell procedure runs with the permissions afforded to the 1269owner of the binary file. 1270.P 1271In the Bourne shell, 1272the 1273.B IFS 1274parameter is used to split each word into separate command arguments. 1275If a user knows that some 1276.I setuid 1277program will run 1278.B "sh \-c /bin/pwd" 1279(or any other command in 1280.BR /bin ) 1281then the user sets and exports 1282.BR IFS=/ . 1283Instead of running 1284.B /bin/pwd 1285the shell will run 1286.B bin 1287with 1288.B pwd 1289as an argument. 1290The user puts his or her own 1291.B bin 1292program into the current directory. 1293This program can 1294create a copy of the shell, 1295make this shell 1296.IR setuid , 1297and then run the 1298.B /bin/pwd 1299program so that the original program continues to run successfully. 1300This kind of penetration is not possible with 1301.I Ksh-i 1302since the 1303.B IFS 1304parameter only splits arguments that result from command or parameter 1305substitution. 1306.P 1307Some 1308.I setuid 1309programs run programs using 1310.I system() 1311without giving the full path name. 1312If the 1313user sets the 1314.B PATH 1315variable so that the desired command will be found 1316in his or her local bin, then the same technique described above can 1317be employed to compromise the security of the system. 1318To close up this and other security holes, 1319.I Ksh-i 1320goes into a 1321.I protected 1322mode whenever the real and effective user or group id are not the same. 1323In this mode, the 1324.B PATH 1325variable is reset to a default value and the 1326.B .profile 1327and 1328.B ENV 1329files are not processed. 1330Instead, the file 1331.B /etc/suid_profile 1332is read and executed. 1333This gives an administrator control over the 1334environment to set the 1335.B PATH 1336variable or to log setuid shell invocations. 1337Clearly security of the system is compromised if 1338.B /etc 1339or this file is publicly writable. 1340.P 1341In BSD UNIX the operating system looks for the characters 1342.B #! 1343as the first two characters of an executable file. 1344If these characters are found, then the next word on this line is taken 1345as the interpreter to 1346.I exec 1347for this command and the interpreter is 1348.IR exec ed 1349with the name of the script as argument zero and argument one. 1350If the 1351.I setuid 1352or 1353.I setgid 1354bits are on for this file, then the interpreter 1355is run with the effective uid and/or gid set accordingly. 1356This scheme has two major drawbacks. 1357First of all, using the 1358.B #! 1359notation forces an 1360.B exec 1361of the interpreter even when the call is invoked from the interpreter 1362which it must exec. This is inefficient since 1363the interpreter can handle a failed exec much faster than starting up 1364again. 1365More importantly, 1366.I setuid 1367and 1368.I setgid 1369procedures provide an easy target for intrusion. 1370By linking a 1371.I setuid 1372or 1373.I setgid 1374procedure to a name beginning with a 1375.B \- 1376the interpreter is fooled into thinking that is being invoked with 1377a command line option rather than the name of a file. 1378When the interpreter is the shell, the user gets a privileged 1379interactive shell. 1380There is code in 1381.I Ksh-i 1382to guard against this simple form of intrusion. 1383.P 1384A more reliable way to handle 1385.I setuid 1386and 1387.I setgid 1388procedures is provided with 1389.IR Ksh-i . 1390The technique does not require any changes to the operating system 1391and provides better security. 1392Another advantage to this method is that it also allows scripts which 1393have execute premission but no read permission to run. Taking away read 1394permission makes scripts more secure. 1395.P 1396The method relies on a setuid 1397.B root 1398program to authenticate the 1399request and exec the shell with the correct mode bits to carry out 1400the task. This shell is invoked with the requested file already open 1401for reading. A script which cannot be opened for reading or which 1402has its suid and/or setgid bits turned on causes this setuid 1403.B root 1404program to get execed. 1405For security reasons, this program is given the full 1406pathname 1407.BR /etc/suid_exec . 1408A description of the implementation of the 1409.B suid_exec 1410program can be found in 1411a separate paper\*(Rf. 1412.RS 1413D. G Korn 1414.I "Parlez-vous Kanji?" 1415TM-59554-860602-03, 1986. 1416.RF 1417.H 1 "Miscellaneous" 1418.P 1419Ksh-i has several additional features to enhance functionality and performance. 1420This section lists most of these features. 1421.H 2 "Tilde substitution" 1422The character 1423.B \(ap 1424at the beginning of a word has special meaning to Ksh-i. 1425If the characters after the 1426.B \(ap 1427up to a 1428.B / 1429match a user login name in the 1430.B /etc/passwd 1431file, then the 1432.B \(ap 1433and the name are replaced by 1434that user's login directory. 1435If no match is found, the original word 1436is unchanged. 1437A 1438.B \(ap 1439by itself, or in front of a 1440.BR / , 1441is replaced by the value of the 1442.B HOME 1443parameter. 1444A 1445.B \(ap 1446followed by a 1447.B + 1448or 1449.B \- 1450is replaced by the value of 1451the parameter 1452.B PWD 1453and 1454.B OLDPWD 1455respectively. 1456Tilde substitution takes place when the script is read, 1457not while it is executed. 1458.H 2 "Built-in I/O Redirection" 1459.P 1460All built-in commands can be redirected. 1461Compound commands which are redirected are not carried out in 1462a separate process. 1463.H 2 "Added options" 1464.P 1465Several options have been added to the shell and 1466all options have names 1467that can be used in place of flags for setting and resetting options. 1468The command 1469.B "set \-o" 1470will list the current option settings. 1471.P 1472The option, 1473.B \-f 1474or 1475.BR noglob , 1476is used to disable file name generation. 1477.P 1478The option 1479.B ignoreeof 1480can be used to prevent 1481.B ^D 1482from exiting the shell and possibly logging you out. 1483You must type 1484.B exit 1485to log out. 1486.P 1487The 1488.B \-h 1489or 1490.B trackall 1491option will cause all commands whose name is a valid alias 1492name to become a 1493.I tracked 1494alias. 1495This option is automatically turned on for non-interactive shells. 1496.P 1497The job 1498.B monitor 1499option will cause a report to be printed 1500before issuing the next prompt 1501when each background job completes. 1502It is automatically enabled for systems that have 1503job control. 1504.P 1505If the 1506.B bgnice 1507option is set, 1508background jobs are run at a lower priority. 1509.P 1510The option 1511.B markdirs 1512causes a trailing 1513.B / 1514to be appended on every directory name resulting from a pattern match. 1515.P 1516The 1517.B protected 1518or 1519.B \-p 1520options provides additional security by disabling the 1521.B ENV 1522from being executed and by resetting the 1523.B PATH 1524variable to the default value. 1525Whenever a shell is run with the effective uid (gid) not equal to 1526the real uid (gid) then this option is implicitly enabled. 1527Instead of the 1528.B ENV 1529file, the file 1530.B /etc/suid_profile 1531is read so that administrators can have control over setuid scripts. 1532.H 2 "Built-in pwd" 1533The 1534.B pwd 1535command is built-into Ksh-i and therefore much faster. 1536.H 2 "Logical naming" 1537The 1538.B cd 1539command will take you where you expect to go even if you cross 1540symbolic links. Thus, 1541.B "cd .." 1542will move you up one level closer to the root even if your 1543current directory is a symbolic link. 1544.H 2 "Previous Directory" 1545.P 1546Ksh-i remembers your last directory 1547in the variable 1548.BR OLDPWD . 1549The 1550.B cd 1551built-in can be given with argument 1552.B \- 1553to return to the previous directory 1554and prints the name of the directory. 1555Note that 1556.B "cd \-" 1557done twice returns you to the starting directory, 1558not the second previous directory. 1559A directory 1560.I stack 1561manager has been written as shell 1562.I functions 1563to 1564.I push 1565and 1566.I pop 1567directories from the stack. 1568.H 2 "Additional Variables and Parameters" 1569.P 1570Several new parameters have special meaning to Ksh-i. 1571The variable 1572.B PWD 1573is used to hold the current working directory of the shell. 1574The variable 1575.B OLDPWD 1576is used to hold the previous working directory of the shell. 1577.P 1578The variable 1579.B FCEDIT 1580is used by the 1581.B fc 1582built-in described above. 1583The variables 1584.B VISUAL 1585and 1586.B EDITOR 1587are used for determining the edit modes as described above. 1588.P 1589The variable 1590.B ENV 1591is used to define the startup file for non-login 1592Ksh-i invocations. 1593.P 1594The variables 1595.B HISTSIZE 1596and 1597.B HISTFILE 1598control the size and location of the file containing 1599commands entered at a terminal. 1600.P 1601The parameter 1602.B MAILPATH 1603is a colon ( 1604.B : 1605) separated list of file names to be checked for changes 1606periodically. The user is notified 1607before the next prompt. 1608Each of the names in this list can be followed by a 1609.B ? 1610and a prompt to be given when a change has been detected in the file. 1611The prompt will be evaluated for parameter substitution. 1612The parameter 1613.B $_ 1614within a mail message will evaluate to the name of the file that 1615has changed. 1616The parameter 1617.B MAILCHECK 1618is used to specify the minimal interval in seconds before 1619new mail is checked for. 1620.P 1621The variable 1622.B RANDOM 1623produces a random number each time it is referenced. 1624Assignment to this variable sets the seed for the 1625random number generator. 1626.P 1627The variable 1628.B SECONDS 1629is incremented every second. 1630In a roundabout way, this variable 1631can be used to generate a time stamp into the 1632.B PS1 1633prompt. 1634The following code explains how you can do this on 1635System V. On BSD you need another command to initialize 1636the 1637.B SECONDS 1638variable. 1639.B 1640.sp 1641.nf 1642.in .5i 1643# If you . this script then you can use $TIME as part of your PS1 string to get 1644# the time of day in your prompt 1645typeset \-RZ2 _x1 _x2 _x3 1646let SECONDS=$(date '+3600*%H+60*%M+%S') 1647_s='(_x1=(SECONDS/3600)%24)==(_x2=(SECONDS/60)%60)==(_x3=SECONDS%60)' 1648TIME='"${_d[_s]}$_x1:$_x2:$_x3"' 1649# PS1=${TIME}whatever 1650.fi 1651.ta 1652.in 1653.sp 1654.R 1655.P 1656The parameter 1657.B PPID 1658is used to generate the process id of the process which invoked this shell. 1659.P 1660The value of the parameter 1661.B _ 1662is the last argument of the previous foreground command. 1663Before execing each command this parameter is set to the file 1664name of the command and placed in the environment. 1665.P 1666The parameter 1667.B TMOUT 1668can be set to be the number of seconds that the shell will wait for 1669input before terminating. A 60 second warning message is printed 1670before terminating. 1671.P 1672The 1673.B COLUMNS 1674variable can be used to adjust the width of the edit window for 1675the in-line edit modes. It is also used by the 1676.B select 1677command to present menu choices. 1678.P 1679The 1680.B LINES 1681variable controls how many rows a select list will take up on the screen. 1682Select lists will try to occupy no more then two-thirds of 1683.B LINES 1684lines on the screen. 1685.H 2 "Modified variables" 1686.P 1687The input field separator parameter, 1688.BR IFS , 1689is only used to split words that have undergone parameter or command 1690substitution. 1691In addition, adjacent non-blank delimiters separate 1692null fields in Ksh-i. 1693.P 1694The 1695.B PS1 1696parameter is evaluated for parameter substitution and a 1697.B ! 1698is replaced by the current command number. 1699.H 2 "Timing Commands" 1700.P 1701A keyword 1702.B time 1703has been added to replace 1704the 1705.B time 1706command. 1707Any function, command or pipeline can be preceded by this keyword 1708to obtain information about the elapsed, user and system times. 1709Since I/O redirection bind to the command, not to 1710.BR time , 1711parenthesis should be used to redirect the timing information which 1712is normally printed on file descriptor 2. 1713.H 2 "Co-process" 1714Ksh-i can spawn a 1715.I co-process 1716by adding a 1717.B "|&" 1718after a command. 1719This process will be run with its standard input and its 1720standard output connected to the shell. The built-in command 1721.B print 1722with the 1723.B \-p 1724option will write into the standard input of this 1725process and 1726the built-in command 1727.B read 1728with the 1729.B \-p 1730option will read from the output of this process. 1731Only one such process can exist at any time. 1732.H 2 "Process Substitution" 1733.P 1734This feature is only available 1735on versions of the UNIX operating system which support the 1736.B /dev/fd 1737directory for naming open files. 1738Each command argument of the form 1739\f3(\fP\f2list\^\fP\f3)\fP, 1740\f3<(\fP\f2list\^\fP\f3)\fP, 1741or 1742\f3>(\fP\f2list\^\fP\f3)\fP 1743will run process 1744.I list 1745asynchronously connected to some file in the 1746.B /dev/fd 1747directory. 1748The name of this file will become the argument to the command. 1749If the form with 1750.B > 1751is selected then writing on this file will provide input for 1752.IR list . 1753If 1754.B < 1755is used or omitted, 1756then the file passed as an argument will contain the output of the 1757.I list 1758process. 1759For example, 1760.B 1761.sp 1762.nf 1763.in .5i 1764paste (cut \-f1 \f2file1\fP) (cut \-f3 \f2file2\fP) | tee >(\f2process1\fP) >(\fP\f2process2\fP) 1765.fi 1766.ta 1767.in 1768.sp 1769.R 1770.I cuts 1771fields 1 and 3 from 1772the files 1773.I file1 1774and 1775.I file2 1776respectively, 1777.I pastes 1778the results together, and 1779sends it 1780to the processes 1781.I process1 1782and 1783.IR process2 , 1784as well as putting it onto the standard output. 1785Note that the file which is passed as an argument to the command is 1786a UNIX 1787.IR pipe (2) 1788so that the programs that expect to 1789.IR lseek (2) 1790on the file will not work. 1791.H 2 "Command Substitution" 1792.P 1793Command substitution ( \fB\(ga\(ga\fR) 1794in the Bourne shell suffers from some 1795complicated quoting rules. 1796It is hard to write a 1797.B sed 1798pattern which contains back slashes within command substitution. 1799Putting the pattern is single quotes doesn't help much. 1800Ksh-i leaves the Bourne shell command substitution alone and adds 1801a newer and easier to use command substitution syntax. 1802All the characters between a 1803.B $( 1804and a matching 1805.B ) 1806are evaluated as a command the output is substituted just as 1807with \fB\(ga\(ga\fR. 1808The 1809.B $ 1810means 1811.I "value of" 1812and the 1813.B () 1814denotes a command. 1815The command itself can contain quoted strings even if the substitution 1816occurs within double quotes. Nesting is legal. You can use 1817unbalanced parenthesis within the command providing that they are 1818quoted. 1819.P 1820The special command substitution of the form 1821\fB$(cat file)\fR 1822can be replaced by 1823\fB$(< file)\fR, 1824which is faster because no separate process is created. 1825.H 2 "Whence" 1826.P 1827The addition of 1828.IR aliases , 1829.IR functions , 1830and more built-ins 1831has made it substantially more difficult to know what 1832a given command word really means. 1833A built-in command, 1834.B whence 1835when used with the 1836.B \-v 1837option has been provided to answer this question. 1838A line is printed for each argument to 1839.B whence 1840telling what would happen if this argument were used as a command name. 1841It reports on keywords, aliases, built-ins, and 1842functions. 1843If the command is none of the above, 1844it follows the path search rules and prints the full path-name, 1845if any, otherwise it prints an error message. 1846.H 2 "Additional test operators" 1847.P 1848The binary operators 1849.B \-ot 1850and 1851.B \-nt 1852can be used to compare the modification times 1853of two files to see which is file is 1854.I "older than" 1855or 1856.I "newer than" 1857the other. 1858The binary operator 1859.B \-ef 1860is used to see if two files 1861have the same device and i-node number, 1862i.\ e., a link to the same file. 1863.P 1864The unary operator 1865.B \-L 1866returns true for a symbolic link. 1867.H 2 "Added Trap" 1868All traps can be given by name in Ksh-i. The names of traps 1869corresponding to signals are the same as the signal name with 1870the 1871.B SIG 1872prefix removed. 1873The trap 1874.B 0 1875is named 1876.B EXIT 1877and a new trap named 1878.B ERR 1879has been added. 1880This trap is invoked whenever the shell would exit if the 1881.B \-e 1882flag were set. 1883This trap is used by 1884Fourth Generation Make\*(Rf 1885.RS 1886G. S. Fowler, 1887"The Fourth Generation Make," 1888Proceedings of the Portland USENIX meeting, pp. 159-174, 1985. 1889.RF 1890which runs Ksh-i 1891as a co-process. 1892.H 2 "Shell Accounting" 1893.P 1894There is a compile time option to the shell to generate 1895an accounting message for each shell script. 1896The changes needed to provide this feature were supplied 1897by Foregger\*(Rf 1898.RS 1899T. H. Foregger, 1900.I "Shell Accounting," 1901Case 40094-21, July 1982. 1902.RF 1903and have been adopted as described in his memo. 1904.H 2 "Coded in Standard C" 1905.P 1906Early versions of Bourne shell were coded in an ALGOL-68 like dialect of C. 1907Ksh-i is coded in standard C. 1908It tries to adapt itself to the environment when it is compiled 1909taking advantages of the features of the host environment when possible. 1910There are far fewer 1911.I lint 1912messages from Ksh-i then for the Bourne shell. 1913Ksh-i does not catch the segmentation violation signal, SIGSEGV, 1914so that it can run on machines that can't recover from these traps. 1915.H 2 Internationization 1916Ksh-i treats eight bit characters transparently without stripping off the 1917leading bit. 1918There is also a compile time switch to enable handling multi-byte 1919and multi-width characters sets. 1920.H 2 "No special meaning for ^" 1921The Bourne shell uses 1922.B ^ 1923as an archaic synonym for 1924.B | . 1925The 1926.B ^ 1927is not a special character to Ksh-i. 1928.H 2 "Added conveniences" 1929You can refer to multi-digit positional parameters in Ksh-i by putting 1930the number in braces. Thus, 1931.B ${12} 1932is legal in Ksh-i but illegal in the Bourne shell. 1933.P 1934Ksh-i will perform file name expansion of file name arguments if the 1935expansion is unique. Thus, 1936.B "cat < file*" 1937will expand the file name if the expansion is unique. 1938.P 1939If you invoke the shell as 1940.B "ksh script" 1941then Ksh-i will do a path search on script. 1942.P 1943Unbalanced quotes will cause the shell to print an 1944error message giving the type of quote and the line number 1945on which the opening quote occurs. 1946.P 1947Run time error messages detected by the shell will print the 1948line number within a function or script where the error was 1949detected. 1950.H 1 "Example" 1951.P 1952An example of a Ksh-i script is included 1953in the Appendix. 1954This one page program is a variant of the UNIX 1955.I grep(1) 1956program. 1957Pattern matching for this version of 1958.I grep 1959means shell patterns consisting of 1960.BR ? , 1961.BR * , 1962and 1963.BR [] . 1964.P 1965The first half examines option flags. 1966Note that all options except 1967.B \-b 1968have been implemented. 1969The second half goes through each line of each file 1970to look for a pattern match. 1971.P 1972This program is not intended to serve as a 1973replacement for 1974.BR grep ; 1975just as an illustration of the programming power of Ksh-i. 1976Note that no auxiliary processes are spawned by this script. 1977It was written and debugged in under two hours. 1978While performance is acceptable for small programs, 1979this program runs at only one tenth 1980the speed of 1981.B grep 1982for large files. 1983.H 1 "Performance" 1984.P 1985Ksh-i executes many scripts faster than the System V Bourne shell. 1986One major reason is that many of the functions provided by 1987.I echo(1) 1988and 1989.I expr(1) 1990are built-in. 1991The time to execute a built-in function is one or two 1992orders of magnitude faster than performing a fork and 1993execute of the shell. 1994Command substitution of built-ins is performed without 1995creating another process, and often without even 1996creating a temporary file. 1997.P 1998Another reason for improved performance is that all I/O is buffered. 1999Output buffers are flushed only when required. 2000Several of the internal algorithms have been changed 2001so that the number of subroutine calls has been 2002substantially reduced. 2003Ksh-i uses hash tables for variables. 2004Scripts that rely heavily on referencing variables execute faster. 2005More processing is performed while reading the script 2006so that execution time is saved while running loops. 2007.P 2008Scripts that do little internal processing and create many processes 2009may run a little slower on System V because the time to 2010.I fork 2011Ksh-i is slightly slower than for the Bourne shell. 2012On BSD Unix, Ksh-i can be compiled with a 2013.B VFORK 2014option which uses 2015.I vfork 2016whenever possible. 2017In this case, binary programs startup somewhat faster but shell 2018script files start a little slower since a separate invocation 2019of the Ksh-i in required. 2020.P 2021The 2022.B ENV 2023file can have an undiserable effect on performance. 2024Even if this file is small, the shell must perform an open of this 2025file. If large functions are placed in 2026the 2027.B ENV 2028file they must be read in and compiled even if they are never referenced. 2029If you only need the startup file for interactive shells only, then set your 2030.B ENV 2031variable to a 2032value which evaluates to a file name for interactive shells and to 2033the null string otherwise. If you export the startup file name 2034in the variable 2035.BR START , 2036then setting 2037.B 2038.sp 2039.nf 2040.in .5i 2041ENV='${START[(_$\-=1)+(_=0)\-(_$\-!=_${\-%%*i*})]}' 2042.fi 2043.ta 2044.in 2045.sp 2046.R 2047will only invoke the startup file for interactive shells 2048since the subscript evaluates to 0 2049only if the shell is interactive. 2050.P 2051If you need a startup 2052.B ENV 2053file for all shells 2054then use a 2055.I case 2056statement on the 2057.B $\- 2058parameter to distinguish which actions only apply to interactive shells. 2059The 2060.B ENV 2061file should look like 2062.B 2063.sp 2064.nf 2065.in .5i 2066# options aliases and functions for all shell invocations 2067case $\- in 2068*i*) 2069 # options aliases and functions for interactive only 2070 ;; 2071esac 2072.fi 2073.ta 2074.in 2075.sp 2076.R 2077.P 2078If there are functions which are only occasionally referenced, put them 2079into a separate file 2080.B $HOME/functions 2081or any name you prefer 2082and put aliases in the 2083.B ENV 2084file for each function name of the form 2085.B 2086.sp 2087.nf 2088.in .5i 2089alias \f2function_name\fP='. $HOME/functions;\f2function_name\fP' 2090.fi 2091.ta 2092.in 2093.sp 2094.R 2095In the beginning of the 2096.B $HOME/functions 2097file you must unalias each of the function names defined in the 2098file. 2099The first reference to any 2100.I function_name 2101in the function file 2102causes the function file to get read in and the functions compiled. 2103.H 1 "Conclusion" 2104.P 2105Ksh-i has several thousand regular users. 2106Ksh-i is a suitable replacement for the Bourne shell. 2107It offers new features, 2108better performance, 2109and is essentially upward compatible with the Bourne shell. 2110.SG dgk \" signature typist initials 2111.NS 0 \" start notation 2112Members of Center 5954 2113Laboratory 4542 Supervision 2114J. W. Gross 2115N. J. Kolettis 2116J. L. Steffen 2117P. D. Sullivan 2118M. T. Veach 2119.NE \" end notation 2120.CS 14 24 38 0 0 16 \" cover sheet for TM 2121.bp 2122.ce 2123APPENDIX 2124.nf 2125 # 2126 # SHELL VERSION OF GREP 2127 # 2128 vflag= xflag= cflag= lflag= nflag= 2129 set \-f 2130 while ((1)) # look for grep options 2131 do case "$1" in 2132 \-v*) vflag=1;; 2133 \-x*) xflag=1;; 2134 \-c*) cflag=1;; 2135 \-l*) lflag=1;; 2136 \-n*) nflag=1;; 2137 \-b*) print \(fmb option not supported\(fm;; 2138 \-e*) shift;expr="$1";; 2139 \-f*) shift;expr=$( < $1 );; 2140 \-*) print $0: \(fmunknown flag\(fm;exit 2;; 2141 *) if test "$expr" = \(fm\|\(fm 2142 then expr="$1";shift 2143 fi 2144 test "$xflag" |\|| expr="*${expr}*" 2145 break;; 2146 esac 2147 shift # next argument 2148 done 2149 noprint=$vflag$cflag$lflag # don't print if these flags set 2150 integer n=0 c=0 tc=0 nargs=$# # initialize counters 2151 for i in "$@" # go through the files 2152 do if ((nargs<=1)) 2153 then fname=\(fm\|\(fm 2154 else fname="$i": 2155 fi 2156 test "$i" && exec 0< $i # open file if necessary 2157 while read \-r line # read in a line 2158 do let n=n+1 2159 case "$line" in 2160 $expr) # line matches pattern 2161 if test "$noprint" = "" 2162 then print \-r "$fname${nflag:+$n:}$line" 2163 fi 2164 let c=c+1 ;; 2165 *) # not a match 2166 if test "$vflag" 2167 then print \-r "$fname${nflag:+$n:}$line" 2168 fi;; 2169 esac 2170 done 2171 if test "$lflag" && ((c)) 2172 then print \- $i 2173 fi 2174 let tc=tc+c n=0 c=0 2175 done 2176 test "$cflag" && print $tc # print count if cflag is set 2177 let tc # set the exit value 2178.fi 2179