1*7a3af63bStb$OpenBSD: NOTES,v 1.14 2016/01/29 11:50:40 tb Exp $ 27cb960a2Sdownsj 33b015934SmillertGeneral features of at&t ksh88 that are not (yet) in pdksh: 43b015934Smillert - exported aliases and functions (not in ksh93). 57cb960a2Sdownsj - set -t. 67cb960a2Sdownsj - signals/traps not cleared during functions. 77cb960a2Sdownsj - trap DEBUG, local ERR and EXIT traps in functions. 8f00c5086Smillert - ERRNO parameter. 97cb960a2Sdownsj - doesn't have posix file globbing (eg, [[:alpha:]], etc.). 107cb960a2Sdownsj - use of an `agent' to execute unreadable/setuid/setgid shell scripts 117cb960a2Sdownsj (don't ask). 12b9f1c854Sdavid - read/select aren't hooked in to the command line editor 13dcacb757Sdownsj - the last command of a pipeline is not run in the parent shell 147cb960a2Sdownsj 157cb960a2SdownsjKnown bugs (see also BUG-REPORTS and PROJECTS files): 167cb960a2Sdownsj Variable parsing, Expansion: 177cb960a2Sdownsj - some specials behave differently when unset (eg, IFS behaves like 187055cce3Sdownsj " \t\n") others lose their special meaning. IFS/PATH taken care of, 197cb960a2Sdownsj still need to sort out some others (eg, TMOUT). 207cb960a2Sdownsj Parsing,Lexing: 21f00c5086Smillert - line numbers in errors are wrong for nested constructs. Need to 227cb960a2Sdownsj keep track of the line a command started on (can use for LINENO 237cb960a2Sdownsj parameter as well). 247cb960a2Sdownsj - a $(..) expression nested inside double quotes inside another $(..) 257cb960a2Sdownsj isn't parsed correctly (eg, $(echo "foo$(echo ")")") ) 267cb960a2Sdownsj Commands,Execution: 277055cce3Sdownsj - setting special parameters that have side effects when 287055cce3Sdownsj changed/restored (ie, HISTFILE, OPTIND, RANDOM) in front 297055cce3Sdownsj of a command (eg, HISTFILE=/foo/bar echo hi) effects the parent 307055cce3Sdownsj shell. Note that setting other (not so special) parameters 317055cce3Sdownsj does not effect the parent shell. 327cb960a2Sdownsj - `echo hi | exec cat -n' causes at&t to exit, `exec echo hi | cat -n' 337cb960a2Sdownsj does not. pdksh exits for neither. Don't think POSIX requires 347cb960a2Sdownsj an exit, but not sure. 357cb960a2Sdownsj - `echo foo | read bar; echo $bar' prints foo in at&t ksh, nothing 36040161f7Smillert in pdksh (ie, the read is done in a separate process in pdksh). 377cb960a2Sdownsj Misc: 387cb960a2Sdownsj 39945abdecSmillertKnown problems not caused by ksh: 40945abdecSmillert - after stoping a job, emacs/vi is not re-entered. Hitting return 41945abdecSmillert prints the prompt and everything is fine again. Problem (often 42945abdecSmillert involving a pager like less) is related to order of process 43945abdecSmillert scheduling (shell runs before `stop'ed (sub) processes have had a chance 44945abdecSmillert to clean up the screen/terminal). 45945abdecSmillert 467cb960a2SdownsjKnown differences between pdksh & at&t ksh (that may change) 477cb960a2Sdownsj - vi: 487cb960a2Sdownsj - `^U': at&t: kills only what has been inserted, pdksh: kills to 497cb960a2Sdownsj start of line 507cb960a2Sdownsj - at&t ksh login shells say "Warning: you have running jobs" if you 517cb960a2Sdownsj try to exit when there are running jobs. An immediate second attempt 527cb960a2Sdownsj to exit will kill the jobs and exit. pdksh does not print a warning, 537cb960a2Sdownsj nor does it kill running jobs when it exits (it does warn/kill for 547cb960a2Sdownsj stopped jobs). 557cb960a2Sdownsj - TMOUT: at&t prints warning, then waits another 60 seconds. If on screwed 567cb960a2Sdownsj up serial line, the output could cause more input, so pdksh just 577cb960a2Sdownsj prints a message and exits. (Also, in at&t ksh, setting TMOUT has no 587cb960a2Sdownsj effect after the sequence "TMOUT=60; unset TMOUT", which could be 597cb960a2Sdownsj useful - pdksh may do this in the future). 607cb960a2Sdownsj - in pdksh, if the last command of a pipeline is a shell builtin, it is 617cb960a2Sdownsj not executed in the parent shell, so "echo a b | read foo bar" does not 627cb960a2Sdownsj set foo and bar in the parent shell (at&t ksh will). 637cb960a2Sdownsj This may get fixed in the future, but it may take a while. 647cb960a2Sdownsj - in pdksh, set +o lists the options that are currently set, in at&t ksh 657cb960a2Sdownsj it is the same as set -o. 667cb960a2Sdownsj - in pdksh emacs mode, ^T does what gnu emacs does, not what at&t ksh 677cb960a2Sdownsj does. 68dcacb757Sdownsj - in ksh93, `. name' calls a function (defined with function) with POSIX 69dcacb757Sdownsj semantics (instead of ksh semantics). in pdksh, . does not call 70dcacb757Sdownsj functions. 717055cce3Sdownsj - test: "test -f foo bar blah" is the same as "test -f foo" (the extra 727055cce3Sdownsj arguments, of which there must be at least 2, are ignored) - pdksh 737055cce3Sdownsj generates an error message (unexpected operator/operand "bar") as it 747055cce3Sdownsj should. Sometimes used to test file globs (e.g., if test -f *.o; ...). 757055cce3Sdownsj - if the command 'sleep 5 && /bin/echo blah' is run interactively and 767055cce3Sdownsj is the sleep is stopped (^Z), the echo is run immediately in pdksh. 777055cce3Sdownsj In at&t ksh, the whole thing is stopped. 78f00c5086Smillert - LINENO: 79f00c5086Smillert - in ksh88 variable is always 1 (can't be changed) in interac mode; 80f00c5086Smillert in pdksh it changes. 81f00c5086Smillert - Value of LINENO after it has been set by the script in one file 82f00c5086Smillert is bizarre when used in another file. 837cb960a2Sdownsj 847cb960a2SdownsjKnown differences between pdksh & at&t ksh (that are not likely to change) 857cb960a2Sdownsj - at&t ksh seems to catch or ignore SIGALRM - pdksh dies upon receipt 867cb960a2Sdownsj (unless it's traped of course) 877cb960a2Sdownsj - typeset: 887cb960a2Sdownsj - at&t ksh overloads -u/-l options: for integers, means unsigned/long, 897cb960a2Sdownsj for strings means uppercase/lowercase; pdksh just has the 907cb960a2Sdownsj upper/lower case (which can be useful for integers when base > 10). 917cb960a2Sdownsj unsigned/long really should have their own options. 927cb960a2Sdownsj - at&t ksh can't have justified integer variables 937cb960a2Sdownsj (eg, typeset -iR5 j=10), pdksh can. 947cb960a2Sdownsj - in pdksh, number arguments for -L/-R/-Z/-i must follow the option 957cb960a2Sdownsj character, at&t allows it at the end of the option group (eg, 967cb960a2Sdownsj at&t ksh likes "typeset -iu5 j", pdksh wants "typeset -i5 -u j" 977cb960a2Sdownsj or "typeset -ui5 j"). Also, pdksh allows "typeset -i 5 j" (same 987cb960a2Sdownsj as "typeset -i5 j"), at&t ksh does not allow this. 997cb960a2Sdownsj - typeset -R: pdksh strips trailing space type characters (ie, 1007cb960a2Sdownsj uses isspace()), at&t ksh only skips blanks. 1017cb960a2Sdownsj - at&t ksh allows attributes of read-only variables to be changed, 1027cb960a2Sdownsj pdksh allows only the export attribute to be set. 103dcacb757Sdownsj - (some) at&t ksh allows set -A of readonly variables, pdksh does not. 1047cb960a2Sdownsj - at&t ksh allows command assignments of readonly variables (eg, YY=2 cat), 1057cb960a2Sdownsj pdksh does not. 1067cb960a2Sdownsj - at&t ksh does not exit scripts when an implicit assignment to an integer 1077cb960a2Sdownsj variable fails due to an expression error: eg, 1087cb960a2Sdownsj echo 2+ > /tmp/x 1097cb960a2Sdownsj unset x; typeset -i x 1107cb960a2Sdownsj read x < /tmp/x 1117cb960a2Sdownsj echo still here 1127cb960a2Sdownsj prints an error and then prints "still here", similarly for 1137cb960a2Sdownsj unset x; typeset -i x 1147cb960a2Sdownsj set +A x 1 2+ 3 1157cb960a2Sdownsj echo still here 1167cb960a2Sdownsj and 1177cb960a2Sdownsj unset x y; typeset -i x y; set +A y 10 20 30 1187cb960a2Sdownsj set +A x 1 1+y[2+] 3 1197cb960a2Sdownsj echo still here 1207cb960a2Sdownsj pdksh exits a script in all the above cases. (note that both shells 1217cb960a2Sdownsj exit for: 1227cb960a2Sdownsj unset x; typeset -i x 1237cb960a2Sdownsj for x in 1 2+ 3; do echo x=$x; done 1247cb960a2Sdownsj echo still here 1257cb960a2Sdownsj ). 1267cb960a2Sdownsj - at&t ksh seems to allow function calls inside expressions 1277cb960a2Sdownsj (eg, typeset -i x='y(2)') but they do not seem to be regular functions 1287cb960a2Sdownsj nor math functions (eg, pow, exp) - anyone known anything about this? 1297cb960a2Sdownsj - `set -o nounset; unset foo; echo ${#foo}`: at&t ksh prints 0; pdksh 1307cb960a2Sdownsj generates error. Same for ${#foo[*]} and ${#foo[@]}. 1317cb960a2Sdownsj - . file: at&t ksh parses the whole file before executing anything, 1327cb960a2Sdownsj pdksh executes as it parses. This means aliases defined in the file 1337cb960a2Sdownsj will affect how pdksh parses the file, but won't affect how at&t ksh 134fe2ad28bSjmc parses the file. Also means pdksh will not parse statements occurring 1357cb960a2Sdownsj after a (executed) return statement. 1367cb960a2Sdownsj - a return in $ENV in at&t ksh will cause the shell to exit, while in 1377cb960a2Sdownsj pdksh it will stop executing the script (this is consistent with 1387cb960a2Sdownsj what a return in .profile does in both shells). 1397cb960a2Sdownsj - at&t ksh does file globbing for `echo "${foo:-"*"}"`, pdksh does not 1407cb960a2Sdownsj (POSIX would seem to indicate pdksh is right). 1417cb960a2Sdownsj - at&t ksh thinks ${a:##foo} is ok, pdksh doesn't. 1427cb960a2Sdownsj - at&t does tilde expansion on here-document delimiters, pdksh does 1437cb960a2Sdownsj not. eg. 1447cb960a2Sdownsj $ cat << ~michael 1457cb960a2Sdownsj ~michael 1467cb960a2Sdownsj $ 1477cb960a2Sdownsj works for pdksh, not for at&t ksh (POSIX seems to agree with pdksh). 1487cb960a2Sdownsj - in at&t ksh, tracked aliases have the export flag implicitly set 1497cb960a2Sdownsj and tracked aliases and normal aliases live in the same name space 1507cb960a2Sdownsj (eg, "alias" will list both tracked and normal aliases). 1517cb960a2Sdownsj in pdksh, -t does not imply -x (since -x doesn't do anything yet), and 152040161f7Smillert tracked/normal aliases live in separate name spaces. 1537cb960a2Sdownsj in at&t ksh, alias accepts + options (eg, +x, +t) - pdksh does not. 1547cb960a2Sdownsj in pdksh, alias has a -d option to allow examination/changing of 1557cb960a2Sdownsj cached ~ entries, also unalias has -d and -t options (unalias -d 1567cb960a2Sdownsj is useful if the ~ cache gets out of date - not sure how at&t deals 1577cb960a2Sdownsj with this problem (it does cache ~ entries)). 1587cb960a2Sdownsj - at&t ksh will stop a recursive function after about 60 calls; pdksh 1597cb960a2Sdownsj will not since the limit is arbitrary and can't be controlled 1607cb960a2Sdownsj by the user (hit ^C if you get in trouble). 1617cb960a2Sdownsj - the wait command (with and without arguments) in at&t ksh will wait for 1627cb960a2Sdownsj stopped jobs when job control is enabled. pdksh doesn't. 1637cb960a2Sdownsj - at&t ksh automatically sets the bgnice option for interactive shells; 1647cb960a2Sdownsj pdksh does not. 1657cb960a2Sdownsj - in at&t ksh, "eval `false`; echo $?" prints 1, pdksh prints 0 (which 1667cb960a2Sdownsj is what POSIX says it should). Same goes for "wait `false`; echo $?". 1677cb960a2Sdownsj (same goes for "set `false`; echo $?" if posix option is set - some 1687cb960a2Sdownsj scripts that use the old getopt depend on this, so be careful about 1697cb960a2Sdownsj setting the posix option). 1707cb960a2Sdownsj - in at&t ksh, print -uX and read -uX are interrperted as -u with no 1717cb960a2Sdownsj argument (defaults to 1 and 0 respectively) and -X (which may or 1727cb960a2Sdownsj may not be a valid flag). In pdksh, -uX is interpreted as file 1737cb960a2Sdownsj descriptor X. 1747cb960a2Sdownsj - in at&t ksh, some signals (HUP, INT, QUIT) cause the read to exit, others 1757cb960a2Sdownsj (ie, everything else) do not. When it does cause exiting, anything read 1767cb960a2Sdownsj to that point is used (usually an empty line) and read returns with 0 1777cb960a2Sdownsj status. pdksh currently does similar things, but for TERM as well and 1787cb960a2Sdownsj the exit status is 128+<signal-number> - in future, pdksh's read will 1797cb960a2Sdownsj do this for all signals that are normally fatal as required by POSIX. 1807cb960a2Sdownsj (POSIX does not require the setting of variables to null so applications 1817cb960a2Sdownsj shouldn't rely on this). 1827cb960a2Sdownsj - in pdksh, ! substitution done before variable substitution; in at&t ksh 183*7a3af63bStb it is done after substitution (and therefore may do ! substitutions on 1847cb960a2Sdownsj the result of variable substitutions). POSIX doesn't say which is to be 1857cb960a2Sdownsj done. 1867cb960a2Sdownsj - pwd: in at&t ksh, it ignores arguments; in pdksh, it complains when given 1877cb960a2Sdownsj arguments. 1887cb960a2Sdownsj - the at&t ksh does not do command substition on PS1, pdksh does. 189dcacb757Sdownsj - ksh93 allows ". foo" to run the function foo if there is no file 190dcacb757Sdownsj called foo (go figure). 191dcacb757Sdownsj - field splitting (IFS): ksh88/ksh93 strip leading non-white space IFS 192dcacb757Sdownsj chars, pdksh (and POSIX, I think) leave them intact. e.g. 193dcacb757Sdownsj $ IFS="$IFS:"; read x; echo "<$x>" 194dcacb757Sdownsj :: 195dcacb757Sdownsj prints "<>" in at&t ksh, "<::>" in pdksh. 196dcacb757Sdownsj - command completion: at&t ksh will do completion on a blank line (matching 197dcacb757Sdownsj all commands), pdksh does not (as this isn't very useful - use * if 198dcacb757Sdownsj you really want the list). 199dcacb757Sdownsj - co-processes: if ksh93, the write portion of the co-process output is 200dcacb757Sdownsj closed when the most recently started co-process exits. pdksh closes 201dcacb757Sdownsj it when all the co-processes using it have exited. 202040161f7Smillert - pdksh accepts empty command lists for while and for statements, while 203040161f7Smillert at&t ksh (and sh) don't. Eg., pdksh likes 204040161f7Smillert while false ; do done 205040161f7Smillert but ksh88 doesn't like it. 206945abdecSmillert - pdksh bumps RANDOM in parent after a fork, at&t ksh bumps it in both 207945abdecSmillert parent and child: 208945abdecSmillert RANDOM=1 209945abdecSmillert echo child: `echo $RANDOM` 210945abdecSmillert echo parent: $RANDOM 211945abdecSmillert will produce "child: 16838 parent: 5758" in pdksh, while at&t ksh 212945abdecSmillert will produce "child: 5758 parent: 5758". 2137cb960a2Sdownsj 2147cb960a2SdownsjOddities in ksh (pd & at&t): 2157cb960a2Sdownsj - array references inside (())/$(()) are strange: 2167cb960a2Sdownsj $(( x[2] )) does the expected, $(( $x[2] )) doesn't. 2177cb960a2Sdownsj - `typeset -R3 X='x '; echo "($X)"` produces ( x) - trailing 2187cb960a2Sdownsj spaces are stripped. 2197cb960a2Sdownsj - typeset -R turns off Z flag. 2207cb960a2Sdownsj - both shells have the following mis-feature: 2217cb960a2Sdownsj $ x='function xx { 2227cb960a2Sdownsj cat -n <<- EOF 2237cb960a2Sdownsj here we are in xx 2247cb960a2Sdownsj EOF 2257cb960a2Sdownsj }' 2267cb960a2Sdownsj $ (eval "$x"; (sleep 2; xx) & echo bye) 2277cb960a2Sdownsj [1] 1234 2287cb960a2Sdownsj bye 2297cb960a2Sdownsj $ xx: /tmp/sh1234.1: cannot open 2307cb960a2Sdownsj - bizarre special handling of alias/export/readonly/typeset arguments 2317cb960a2Sdownsj $ touch a=a; typeset a=[ab]; echo "$a" 2327cb960a2Sdownsj a=[ab] 2337cb960a2Sdownsj $ x=typeset; $x a=[ab]; echo "$a" 2347cb960a2Sdownsj a=a 2357cb960a2Sdownsj $ 2367cb960a2Sdownsj - both ignore SIGTSTP,SIGTTIN,SIGTTOU in exec'd processes when talking 2377cb960a2Sdownsj and not monitoring (at&t ksh kind of does this). Doesn't really make 2387cb960a2Sdownsj sense. 2397cb960a2Sdownsj (Note that ksh.att -ic 'set +m; check-sigs' shows TSTP et al aren't 2407cb960a2Sdownsj ignored, while ksh.att -ic 'set +m^J check-sigs' does... very strange) 2417cb960a2Sdownsj - when tracing (set -x), and a command's stderr is redirected, the trace 2427cb960a2Sdownsj output is also redirected. so "set -x; echo foo 2> /tmp/O > /dev/null" 2437cb960a2Sdownsj will create /tmp/foo with the lines "+ > /dev/null" and "+ echo foo". 2447cb960a2Sdownsj - undocumented at&t ksh feature: FPATH is searched after PATH if no 2457cb960a2Sdownsj executable is found, even if typeset -uf wasn't used. 2467cb960a2Sdownsj 2477cb960a2SdownsjPOSIX sh questions (references are to POSIX 1003.2-1992) 2487cb960a2Sdownsj - arithmetic expressions: how are empty expressions treated? 2497cb960a2Sdownsj (eg, echo $(( ))). at&t ksh (and now pdksh) echo 0. 2507cb960a2Sdownsj Same question goes for `test "" -eq 0' - does this generate an error 2517cb960a2Sdownsj or, if not, what is the exit code? 2527cb960a2Sdownsj - should tilde expansion occur after :'s in the word part of ${..=..}? 2537cb960a2Sdownsj (me thinks it should) 2547cb960a2Sdownsj - if a signal is received during the execution of a built-in, 2557cb960a2Sdownsj does the builtin command exit or the whole shell? 2567cb960a2Sdownsj - is it legal to execute last command of pipeline in current 2577cb960a2Sdownsj execution environment (eg, can "echo foo | read bar" set 2587cb960a2Sdownsj bar?) 2597cb960a2Sdownsj - what action should be taken if there is an error doing a dup due 2607cb960a2Sdownsj to system limits (eg, not enough feil destriptors): is this 26196315c49Sfgsch a "redirection error" (in which case a script will exit iff the 2627cb960a2Sdownsj error occured while executing a special built-in)? 2637cb960a2Sdownsj IMHO, shell should exit script. Couldn't find a blanket statement 2647cb960a2Sdownsj like "if shell encounters an unexpected system error, it shall 2657cb960a2Sdownsj exit non-interactive scripts"... 2667cb960a2Sdownsj 2677cb960a2SdownsjPOSIX sh bugs (references are to POSIX 1003.2-1992) 2687cb960a2Sdownsj - in vi insert mode, ^W deletes to beginning of line or to the first 2697cb960a2Sdownsj blank/punct character (para at line 9124, section 3). This means 2707cb960a2Sdownsj "foo ^W" will do nothing. This is inconsistent with the vi 2717cb960a2Sdownsj spec, which says delete preceding word including and interceding 2727cb960a2Sdownsj blanks (para at line 5189, section 5). 2737cb960a2Sdownsj - parameter expansion, section 3.6.2, line 391: `in each case that a 2747cb960a2Sdownsj value of word is needed (..), word shall be subjected to tilde 2757cb960a2Sdownsj expansion, parameter expansion, ...'. Various expansions should not 2767cb960a2Sdownsj be performed if parameter is in double quotes. 2777cb960a2Sdownsj - the getopts description says assigning OPTIND a value other than 1 2787cb960a2Sdownsj produces undefined results, while the rationale for getopts suggests 2797cb960a2Sdownsj saving/restoring the OPTIND value inside functions (since POSIX 2807cb960a2Sdownsj functions don't do the save/restore automatically). Restoring 2817cb960a2Sdownsj OPTIND is kind of dumb since getopts may have been in the middle 2827cb960a2Sdownsj of parsing a group of flags (eg, -abc). 2837cb960a2Sdownsj - unclear whether arithmetic expressions (eg, $((..))) should 2847cb960a2Sdownsj understand C integer constants (ie, 0x123, 0177). at&t ksh doesn't 2857cb960a2Sdownsj and neither does pdksh. 2867cb960a2Sdownsj - `...` definition (3.6.3) says nothing about backslash followed by 2877cb960a2Sdownsj a newline, which sh and at&t ksh strip out completely. e.g., 2887cb960a2Sdownsj $ show-args `echo 'X 2897cb960a2Sdownsj Y'` 2907cb960a2Sdownsj Number of args: 1 2917cb960a2Sdownsj 1: <XY> 2927cb960a2Sdownsj $ 2937cb960a2Sdownsj POSIX would indicate the backslash-newline would be preserved. 2947cb960a2Sdownsj - does not say how "cat << ''" is to be treated (illegal, read 'til 2957cb960a2Sdownsj blank line, or read 'til eof). at&t ksh reads til eof, bourne shell 2967cb960a2Sdownsj reads 'til blank line. pdksh reads 'til blank line. 297