1*f00c5086Smillert$OpenBSD: NOTES,v 1.7 1999/06/15 01:18:33 millert 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. 8*f00c5086Smillert - 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). 12dcacb757Sdownsj - read/select aren't hooked in to the 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: 21*f00c5086Smillert - 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. 78*f00c5086Smillert - LINENO: 79*f00c5086Smillert - in ksh88 variable is always 1 (can't be changed) in interac mode; 80*f00c5086Smillert in pdksh it changes. 81*f00c5086Smillert - Value of LINENO after it has been set by the script in one file 82*f00c5086Smillert 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 1347cb960a2Sdownsj parses the file. Also means pdksh will not parse statements occuring 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 1837cb960a2Sdownsj it is done after substitution (and therefor 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 2477cb960a2Sdownsjat&t ksh bugs: 2487cb960a2Sdownsj [various versions: 2497cb960a2Sdownsj MIPS m120 RISC/os 5.0: Version 11/16/88d 2507cb960a2Sdownsj Dec alpha osf/1 v1.3: OSF/1 Version 11/16/88d NLS 2517cb960a2Sdownsj HP pa HP-UX 9.01: Version 11/16/88 2527cb960a2Sdownsj ] 2537cb960a2Sdownsj - (only hpux) 2547cb960a2Sdownsj $ _[2]=hi 2557cb960a2Sdownsj Bus error (core dumped) 2567cb960a2Sdownsj - (only riscos, hpux) 2577cb960a2Sdownsj $ typeset x[ 2587cb960a2Sdownsj $ 2597cb960a2Sdownsj - (only osf/1) 2607cb960a2Sdownsj $ A=B cat << EOF 2617cb960a2Sdownsj .$A. 2627cb960a2Sdownsj EOF 2637cb960a2Sdownsj Segmentation fault(coredump) 2647cb960a2Sdownsj $ 2657cb960a2Sdownsj - (only osf/1) 2667cb960a2Sdownsj $ read "?foo " 2677cb960a2Sdownsj foo Foo 2687cb960a2Sdownsj $ set | grep Foo 2697cb960a2Sdownsj =Foo 2707cb960a2Sdownsj $ 2717cb960a2Sdownsj - (all) 2727cb960a2Sdownsj $ typeset -i A 2737cb960a2Sdownsj $ typeset -L3 A 2747cb960a2Sdownsj $ typeset -l A 2757cb960a2Sdownsj Illegal instruction (core dumped) 2767cb960a2Sdownsj - (all) 2777cb960a2Sdownsj $ for i in a b c ; do echo $i, ${i[2]}, ${i[10]} ; done 2787cb960a2Sdownsj a, , 2797cb960a2Sdownsj a, , b 2807cb960a2Sdownsj a, , c 2817cb960a2Sdownsj $ 2827cb960a2Sdownsj - (all) 2837cb960a2Sdownsj $ echo ${abc:-G { I } K } 2847cb960a2Sdownsj G { I K } 2857cb960a2Sdownsj $ 2867cb960a2Sdownsj $ abc=hi 2877cb960a2Sdownsj $ echo ${abc:-G { I } K } 2887cb960a2Sdownsj hi K } 2897cb960a2Sdownsj $ 2907cb960a2Sdownsj The second echo should only have printed `hi'. 2917cb960a2Sdownsj - (all) 2927cb960a2Sdownsj $ echo ${abc:- > foo} 2937cb960a2Sdownsj syntax error: > unexpected 2947cb960a2Sdownsj $ 2957cb960a2Sdownsj - (all? hpux) read reads too much from pipe (when pipe isn't stdin) 2967cb960a2Sdownsj print 'hi\nthere' | ksh 8<&0 0< /dev/tty 2977cb960a2Sdownsj $ read -u8 x 2987cb960a2Sdownsj $ print $x 2997cb960a2Sdownsj hi 3007cb960a2Sdownsj $ cat 0<&8 3017cb960a2Sdownsj $ read -u8 y 3027cb960a2Sdownsj $ print $y 3037cb960a2Sdownsj there 3047cb960a2Sdownsj $ 3057cb960a2Sdownsj - (all) 3067cb960a2Sdownsj $ umask 0 3077cb960a2Sdownsj $ umask 3087cb960a2Sdownsj 00 3097cb960a2Sdownsj $ 3107cb960a2Sdownsj - (osf, mips, !hpux) 3117cb960a2Sdownsj $ exec alias 3127cb960a2Sdownsj alias: not found 3137cb960a2Sdownsj (shell dead) 3147cb960a2Sdownsj - (all) non-white space IFS in non-substitution not preserved 3157cb960a2Sdownsj $ IFS="$IFS:" 3167cb960a2Sdownsj $ echo : "$@" # this is ok 3177cb960a2Sdownsj : 3187cb960a2Sdownsj $ echo :"$@" # this should print : too (me thinks) 3197cb960a2Sdownsj 3207cb960a2Sdownsj $ 3217cb960a2Sdownsj - (only osf/1) 3227cb960a2Sdownsj $ set +m 3237cb960a2Sdownsj $ sleep 1 & # wait for a sec or two 3247cb960a2Sdownsj $ jobs 3257cb960a2Sdownsj Memory fault (core dumped) 3267cb960a2Sdownsj - (all) 3277cb960a2Sdownsj $ (sleep 1 & echo hi) & 3287cb960a2Sdownsj [1] 123 3297cb960a2Sdownsj $ [1] 234 3307cb960a2Sdownsj hi 3317cb960a2Sdownsj - (osf/1, mips) 3327cb960a2Sdownsj $ getopts abc optc -a -b -c 3337cb960a2Sdownsj $ getopts abc optc -a -b -c 3347cb960a2Sdownsj $ getopts abc optc -a 3357cb960a2Sdownsj Memory fault (core dumped) 3367cb960a2Sdownsj - (osf/1) POSIX says OPTIND shall be initialized to 1 3377cb960a2Sdownsj $ echo $OPTIND 3387cb960a2Sdownsj 0 3397cb960a2Sdownsj $ 3407cb960a2Sdownsj - (osf/1 + others?) 3417cb960a2Sdownsj $ typeset -ri r=10 3427cb960a2Sdownsj $ let r=12 3437cb960a2Sdownsj $ echo $r 3447cb960a2Sdownsj 12 3457cb960a2Sdownsj $ 3467cb960a2Sdownsj - (osf/1 + others?) 3477cb960a2Sdownsj $ typeset -i a 3487cb960a2Sdownsj $ typeset -L3 a 3497cb960a2Sdownsj Memory fault (core dumped) 3507cb960a2Sdownsj - (osf/1 + others?): -L strips leading \ \t\n\r, -R only strips trailing 3517cb960a2Sdownsj spaces 3527cb960a2Sdownsj $ typeset -L3 x 3537cb960a2Sdownsj $ x=' ^I^J^M 2' 3547cb960a2Sdownsj $ echo "($x)" 3557cb960a2Sdownsj (2 ) 3567cb960a2Sdownsj $ typeset -R3 y 3577cb960a2Sdownsj $ x='2^I^J^M ' 3587cb960a2Sdownsj $ echo "($x)" 3597cb960a2Sdownsj (^I^J^M) 3607cb960a2Sdownsj $ 3617cb960a2Sdownsj - (osf/1 + others?) 3627cb960a2Sdownsj $ typeset +i RANDOM 3637cb960a2Sdownsj Memory fault (core dumped) 3647cb960a2Sdownsj - (osf/1 + others?): -L/-R/-Z clear -l/-u after assignment and vise versa 3657cb960a2Sdownsj $ typeset -u x=ab 3667cb960a2Sdownsj $ echo "($x)" 3677cb960a2Sdownsj (AB) 3687cb960a2Sdownsj $ typeset -L4 x=def 3697cb960a2Sdownsj $ echo "($x)" 3707cb960a2Sdownsj (DEF ) 3717cb960a2Sdownsj $ typeset | grep ' x$' 3727cb960a2Sdownsj leftjust 4 x 3737cb960a2Sdownsj $ 3747cb960a2Sdownsj $ typeset -L4 x=def 3757cb960a2Sdownsj $ echo "($x)" 3767cb960a2Sdownsj (def ) 3777cb960a2Sdownsj $ typeset -u x=ab 3787cb960a2Sdownsj $ echo "($x)" 3797cb960a2Sdownsj (AB ) 3807cb960a2Sdownsj $ typeset | grep ' x$' 3817cb960a2Sdownsj uppercase x 3827cb960a2Sdownsj $ 3837cb960a2Sdownsj $ typeset -i x 3847cb960a2Sdownsj $ x='2()' 3857cb960a2Sdownsj $ x='()' 3867cb960a2Sdownsj $ x='2(4)' 3877cb960a2Sdownsj - (osf/1, others?) 3887cb960a2Sdownsj $ unset foo 3897cb960a2Sdownsj $ echo "${foo:-"*"}" 3907cb960a2Sdownsj <results of * expansion> 3917cb960a2Sdownsj $ 3927cb960a2Sdownsj - (osf/1, others?) 3937cb960a2Sdownsj $ alias blah 3947cb960a2Sdownsj blah: alias not found 3957cb960a2Sdownsj $ alias -x blah | grep blah 3967cb960a2Sdownsj blah 3977cb960a2Sdownsj $ type blah 3987cb960a2Sdownsj Memory fault (core dumped) 3997cb960a2Sdownsj - (osf/1, others?) 4007cb960a2Sdownsj $ trap 'echo hi; false' ERR 4017cb960a2Sdownsj $ false 4027cb960a2Sdownsj hi 4037cb960a2Sdownsj hi 4047cb960a2Sdownsj .... 4057cb960a2Sdownsj Memory fault (core dumped) 4067cb960a2Sdownsj - (osf/1, others?) 4077cb960a2Sdownsj $ typeset +i ERRNO 4087cb960a2Sdownsj Memory fault (core dumped) 4097cb960a2Sdownsj - (osf/1, others?) 4107cb960a2Sdownsj $ X=abcdef 4117cb960a2Sdownsj $ echo ${X#a{b,c}e} # does not match {} inside word part of ${..#..} 4127cb960a2Sdownsj abcdefe} 4137cb960a2Sdownsj $ 4147cb960a2Sdownsj - (osf/1, others?) 4157cb960a2Sdownsj $ x=f=abcdef 4167cb960a2Sdownsj $ echo ${f#a|abc} 4177cb960a2Sdownsj def 4187cb960a2Sdownsj $ echo ${f#abc|a} 4197cb960a2Sdownsj bcdef 4207cb960a2Sdownsj $ echo ${f#abc|a|d} 4217cb960a2Sdownsj abcdef 4227cb960a2Sdownsj $ 4237cb960a2Sdownsj - (osf/1, hp-ux, others?) 4247cb960a2Sdownsj $ i() echo hi 4257cb960a2Sdownsj $ typeset -f 4267cb960a2Sdownsj function i 4277cb960a2Sdownsj { 4287cb960a2Sdownsj hi 4297cb960a2Sdownsj $ 4307cb960a2Sdownsj - (osf/1, others?) 4317cb960a2Sdownsj $ function X { 4327cb960a2Sdownsj echo start of X 4337cb960a2Sdownsj function Y { 4347cb960a2Sdownsj echo in Y 4357cb960a2Sdownsj } 4367cb960a2Sdownsj echo end of X 4377cb960a2Sdownsj } 4387cb960a2Sdownsj $ X 4397cb960a2Sdownsj start of X 4407cb960a2Sdownsj end of X 4417cb960a2Sdownsj $ typeset -f 4427cb960a2Sdownsj function X 4437cb960a2Sdownsj { 4447cb960a2Sdownsj echo start of X 4457cb960a2Sdownsj function Y { 4467cb960a2Sdownsj echo in Y 4477cb960a2Sdownsj } 4487cb960a2Sdownsj echo end of X 4497cb960a2Sdownsj } 4507cb960a2Sdownsj function Y 4517cb960a2Sdownsj { 4527cb960a2Sdownsj echo in Y 4537cb960a2Sdownsj echo end of X 4547cb960a2Sdownsj } 4557cb960a2Sdownsj } 4567cb960a2Sdownsj $ 4577cb960a2Sdownsj - (osf/1, others?) 4587cb960a2Sdownsj $ while read x; do print -r "A $x"; done |& 4597cb960a2Sdownsj [1] 18212 4607cb960a2Sdownsj $ exec 8<&p 4617cb960a2Sdownsj $ kill %1 4627cb960a2Sdownsj Memory fault 4637cb960a2Sdownsj - (osf/1, others?) Error only happens for builtin commands (/bin/echo works) 4647cb960a2Sdownsj $ while read x; do print -r "A $x"; done |& 4657cb960a2Sdownsj [1] 18212 4667cb960a2Sdownsj $ echo hi <&p 4677cb960a2Sdownsj hi 4687cb960a2Sdownsj $ echo hi <&p 4697cb960a2Sdownsj ksh: p: bad file unit number 4707cb960a2Sdownsj $ while read x; do print -r "A $x"; done |& 4717cb960a2Sdownsj ksh: process already exists 4727cb960a2Sdownsj $ 4737cb960a2Sdownsj - (osf/1, others?) in restricted shells, command -p should not work. 4747cb960a2Sdownsj $ PATH=/tmp ksh -r 4757cb960a2Sdownsj $ print hi | command -p cat -n 4767cb960a2Sdownsj 1 hi 4777cb960a2Sdownsj $ 4787cb960a2Sdownsj - (osf/1, others?) error message wrong for autoload files that don't define 4797cb960a2Sdownsj functions 4807cb960a2Sdownsj $ FPATH=/tmp 4817cb960a2Sdownsj $ echo echo hi there > /tmp/aja 4827cb960a2Sdownsj $ aja 4837cb960a2Sdownsj hi there 4847cb960a2Sdownsj ksh: echo: not found 4857cb960a2Sdownsj $ 4863b015934Smillert - (SunOS M-12/28/93d): 4873b015934Smillert $ cat -n << X $( 4883b015934Smillert > echo foo 4893b015934Smillert > ) 4903b015934Smillert > X 4913b015934Smillert > echo bar 4923b015934Smillert ) 4933b015934Smillert ./ksh93: X: cannot open [No such file or directory] 4943b015934Smillert Memory fault (core dumped) 4957cb960a2Sdownsj 4967cb960a2SdownsjPOSIX sh questions (references are to POSIX 1003.2-1992) 4977cb960a2Sdownsj - arithmetic expressions: how are empty expressions treated? 4987cb960a2Sdownsj (eg, echo $(( ))). at&t ksh (and now pdksh) echo 0. 4997cb960a2Sdownsj Same question goes for `test "" -eq 0' - does this generate an error 5007cb960a2Sdownsj or, if not, what is the exit code? 5017cb960a2Sdownsj - should tilde expansion occur after :'s in the word part of ${..=..}? 5027cb960a2Sdownsj (me thinks it should) 5037cb960a2Sdownsj - if a signal is received during the execution of a built-in, 5047cb960a2Sdownsj does the builtin command exit or the whole shell? 5057cb960a2Sdownsj - is it legal to execute last command of pipeline in current 5067cb960a2Sdownsj execution environment (eg, can "echo foo | read bar" set 5077cb960a2Sdownsj bar?) 5087cb960a2Sdownsj - what action should be taken if there is an error doing a dup due 5097cb960a2Sdownsj to system limits (eg, not enough feil destriptors): is this 5107cb960a2Sdownsj a "redirection error" (in which case a script will exit iff the 5117cb960a2Sdownsj error occured while executing a special built-in)? 5127cb960a2Sdownsj IMHO, shell should exit script. Couldn't find a blanket statement 5137cb960a2Sdownsj like "if shell encounters an unexpected system error, it shall 5147cb960a2Sdownsj exit non-interactive scripts"... 5157cb960a2Sdownsj 5167cb960a2SdownsjPOSIX sh bugs (references are to POSIX 1003.2-1992) 5177cb960a2Sdownsj - in vi insert mode, ^W deletes to beginning of line or to the first 5187cb960a2Sdownsj blank/punct character (para at line 9124, section 3). This means 5197cb960a2Sdownsj "foo ^W" will do nothing. This is inconsistent with the vi 5207cb960a2Sdownsj spec, which says delete preceding word including and interceding 5217cb960a2Sdownsj blanks (para at line 5189, section 5). 5227cb960a2Sdownsj - parameter expansion, section 3.6.2, line 391: `in each case that a 5237cb960a2Sdownsj value of word is needed (..), word shall be subjected to tilde 5247cb960a2Sdownsj expansion, parameter expansion, ...'. Various expansions should not 5257cb960a2Sdownsj be performed if parameter is in double quotes. 5267cb960a2Sdownsj - the getopts description says assigning OPTIND a value other than 1 5277cb960a2Sdownsj produces undefined results, while the rationale for getopts suggests 5287cb960a2Sdownsj saving/restoring the OPTIND value inside functions (since POSIX 5297cb960a2Sdownsj functions don't do the save/restore automatically). Restoring 5307cb960a2Sdownsj OPTIND is kind of dumb since getopts may have been in the middle 5317cb960a2Sdownsj of parsing a group of flags (eg, -abc). 5327cb960a2Sdownsj - unclear whether arithmetic expressions (eg, $((..))) should 5337cb960a2Sdownsj understand C integer constants (ie, 0x123, 0177). at&t ksh doesn't 5347cb960a2Sdownsj and neither does pdksh. 5357cb960a2Sdownsj - `...` definition (3.6.3) says nothing about backslash followed by 5367cb960a2Sdownsj a newline, which sh and at&t ksh strip out completely. e.g., 5377cb960a2Sdownsj $ show-args `echo 'X 5387cb960a2Sdownsj Y'` 5397cb960a2Sdownsj Number of args: 1 5407cb960a2Sdownsj 1: <XY> 5417cb960a2Sdownsj $ 5427cb960a2Sdownsj POSIX would indicate the backslash-newline would be preserved. 5437cb960a2Sdownsj - does not say how "cat << ''" is to be treated (illegal, read 'til 5447cb960a2Sdownsj blank line, or read 'til eof). at&t ksh reads til eof, bourne shell 5457cb960a2Sdownsj reads 'til blank line. pdksh reads 'til blank line. 546