1*dcacb757Sdownsj$OpenBSD: NOTES,v 1.2 1996/08/19 20:08:43 downsj Exp $ 27cb960a2Sdownsj 37cb960a2SdownsjGeneral features of at&t ksh that are not (yet) in pdksh: 47cb960a2Sdownsj - exported aliases. 57cb960a2Sdownsj - exported functions. 67cb960a2Sdownsj - set -t. 77cb960a2Sdownsj - signals/traps not cleared during functions. 87cb960a2Sdownsj - trap DEBUG, local ERR and EXIT traps in functions. 9*dcacb757Sdownsj - ERRNO, LINENO parameters. 107cb960a2Sdownsj - doesn't have posix file globbing (eg, [[:alpha:]], etc.). 117cb960a2Sdownsj - use of an `agent' to execute unreadable/setuid/setgid shell scripts 127cb960a2Sdownsj (don't ask). 13*dcacb757Sdownsj - read/select aren't hooked in to the the command line editor 14*dcacb757Sdownsj - the last command of a pipeline is not run in the parent shell 157cb960a2Sdownsj 167cb960a2SdownsjKnown bugs (see also BUG-REPORTS and PROJECTS files): 177cb960a2Sdownsj Variable parsing, Expansion: 187cb960a2Sdownsj - some specials behave differently when unset (eg, IFS behaves like 197cb960a2Sdownsj " \t\n") others loose their special meaning. IFS/PATH taken care of, 207cb960a2Sdownsj still need to sort out some others (eg, TMOUT). 217cb960a2Sdownsj Parsing,Lexing: 227cb960a2Sdownsj - line numbers in errors are wrong for nested construct. Need to 237cb960a2Sdownsj keep track of the line a command started on (can use for LINENO 247cb960a2Sdownsj parameter as well). 257cb960a2Sdownsj - a $(..) expression nested inside double quotes inside another $(..) 267cb960a2Sdownsj isn't parsed correctly (eg, $(echo "foo$(echo ")")") ) 277cb960a2Sdownsj Commands,Execution: 287cb960a2Sdownsj - setting special parameters in front of a command 297cb960a2Sdownsj (eg, HISTFILE=/foo/bar echo hi) effects the parent shell... 307cb960a2Sdownsj - `echo hi | exec cat -n' causes at&t to exit, `exec echo hi | cat -n' 317cb960a2Sdownsj does not. pdksh exits for neither. Don't think POSIX requires 327cb960a2Sdownsj an exit, but not sure. 337cb960a2Sdownsj - `echo foo | read bar; echo $bar' prints foo in at&t ksh, nothing 347cb960a2Sdownsj in pdksh (ie, the read is done in a seperate process in pdksh). 357cb960a2Sdownsj Misc: 367cb960a2Sdownsj 377cb960a2SdownsjKnown differences between pdksh & at&t ksh (that may change) 387cb960a2Sdownsj - vi: 397cb960a2Sdownsj - `^U': at&t: kills only what has been inserted, pdksh: kills to 407cb960a2Sdownsj start of line 417cb960a2Sdownsj - at&t ksh login shells say "Warning: you have running jobs" if you 427cb960a2Sdownsj try to exit when there are running jobs. An immediate second attempt 437cb960a2Sdownsj to exit will kill the jobs and exit. pdksh does not print a warning, 447cb960a2Sdownsj nor does it kill running jobs when it exits (it does warn/kill for 457cb960a2Sdownsj stopped jobs). 467cb960a2Sdownsj - TMOUT: at&t prints warning, then waits another 60 seconds. If on screwed 477cb960a2Sdownsj up serial line, the output could cause more input, so pdksh just 487cb960a2Sdownsj prints a message and exits. (Also, in at&t ksh, setting TMOUT has no 497cb960a2Sdownsj effect after the sequence "TMOUT=60; unset TMOUT", which could be 507cb960a2Sdownsj useful - pdksh may do this in the future). 517cb960a2Sdownsj - in pdksh, if the last command of a pipeline is a shell builtin, it is 527cb960a2Sdownsj not executed in the parent shell, so "echo a b | read foo bar" does not 537cb960a2Sdownsj set foo and bar in the parent shell (at&t ksh will). 547cb960a2Sdownsj This may get fixed in the future, but it may take a while. 557cb960a2Sdownsj - in pdksh, set +o lists the options that are currently set, in at&t ksh 567cb960a2Sdownsj it is the same as set -o. 577cb960a2Sdownsj - in pdksh emacs mode, ^T does what gnu emacs does, not what at&t ksh 587cb960a2Sdownsj does. 59*dcacb757Sdownsj - in ksh93, `. name' calls a function (defined with function) with POSIX 60*dcacb757Sdownsj semantics (instead of ksh semantics). in pdksh, . does not call 61*dcacb757Sdownsj functions. 627cb960a2Sdownsj 637cb960a2SdownsjKnown differences between pdksh & at&t ksh (that are not likely to change) 647cb960a2Sdownsj - at&t ksh seems to catch or ignore SIGALRM - pdksh dies upon receipt 657cb960a2Sdownsj (unless it's traped of course) 667cb960a2Sdownsj - typeset: 677cb960a2Sdownsj - at&t ksh overloads -u/-l options: for integers, means unsigned/long, 687cb960a2Sdownsj for strings means uppercase/lowercase; pdksh just has the 697cb960a2Sdownsj upper/lower case (which can be useful for integers when base > 10). 707cb960a2Sdownsj unsigned/long really should have their own options. 717cb960a2Sdownsj - at&t ksh can't have justified integer variables 727cb960a2Sdownsj (eg, typeset -iR5 j=10), pdksh can. 737cb960a2Sdownsj - in pdksh, number arguments for -L/-R/-Z/-i must follow the option 747cb960a2Sdownsj character, at&t allows it at the end of the option group (eg, 757cb960a2Sdownsj at&t ksh likes "typeset -iu5 j", pdksh wants "typeset -i5 -u j" 767cb960a2Sdownsj or "typeset -ui5 j"). Also, pdksh allows "typeset -i 5 j" (same 777cb960a2Sdownsj as "typeset -i5 j"), at&t ksh does not allow this. 787cb960a2Sdownsj - typeset -R: pdksh strips trailing space type characters (ie, 797cb960a2Sdownsj uses isspace()), at&t ksh only skips blanks. 807cb960a2Sdownsj - at&t ksh allows attributes of read-only variables to be changed, 817cb960a2Sdownsj pdksh allows only the export attribute to be set. 82*dcacb757Sdownsj - (some) at&t ksh allows set -A of readonly variables, pdksh does not. 837cb960a2Sdownsj - at&t ksh allows command assignments of readonly variables (eg, YY=2 cat), 847cb960a2Sdownsj pdksh does not. 857cb960a2Sdownsj - at&t ksh does not exit scripts when an implicit assignment to an integer 867cb960a2Sdownsj variable fails due to an expression error: eg, 877cb960a2Sdownsj echo 2+ > /tmp/x 887cb960a2Sdownsj unset x; typeset -i x 897cb960a2Sdownsj read x < /tmp/x 907cb960a2Sdownsj echo still here 917cb960a2Sdownsj prints an error and then prints "still here", similarly for 927cb960a2Sdownsj unset x; typeset -i x 937cb960a2Sdownsj set +A x 1 2+ 3 947cb960a2Sdownsj echo still here 957cb960a2Sdownsj and 967cb960a2Sdownsj unset x y; typeset -i x y; set +A y 10 20 30 977cb960a2Sdownsj set +A x 1 1+y[2+] 3 987cb960a2Sdownsj echo still here 997cb960a2Sdownsj pdksh exits a script in all the above cases. (note that both shells 1007cb960a2Sdownsj exit for: 1017cb960a2Sdownsj unset x; typeset -i x 1027cb960a2Sdownsj for x in 1 2+ 3; do echo x=$x; done 1037cb960a2Sdownsj echo still here 1047cb960a2Sdownsj ). 1057cb960a2Sdownsj - at&t ksh seems to allow function calls inside expressions 1067cb960a2Sdownsj (eg, typeset -i x='y(2)') but they do not seem to be regular functions 1077cb960a2Sdownsj nor math functions (eg, pow, exp) - anyone known anything about this? 1087cb960a2Sdownsj - `set -o nounset; unset foo; echo ${#foo}`: at&t ksh prints 0; pdksh 1097cb960a2Sdownsj generates error. Same for ${#foo[*]} and ${#foo[@]}. 1107cb960a2Sdownsj - . file: at&t ksh parses the whole file before executing anything, 1117cb960a2Sdownsj pdksh executes as it parses. This means aliases defined in the file 1127cb960a2Sdownsj will affect how pdksh parses the file, but won't affect how at&t ksh 1137cb960a2Sdownsj parses the file. Also means pdksh will not parse statements occuring 1147cb960a2Sdownsj after a (executed) return statement. 1157cb960a2Sdownsj - a return in $ENV in at&t ksh will cause the shell to exit, while in 1167cb960a2Sdownsj pdksh it will stop executing the script (this is consistent with 1177cb960a2Sdownsj what a return in .profile does in both shells). 1187cb960a2Sdownsj - at&t ksh does file globbing for `echo "${foo:-"*"}"`, pdksh does not 1197cb960a2Sdownsj (POSIX would seem to indicate pdksh is right). 1207cb960a2Sdownsj - at&t ksh thinks ${a:##foo} is ok, pdksh doesn't. 1217cb960a2Sdownsj - at&t does tilde expansion on here-document delimiters, pdksh does 1227cb960a2Sdownsj not. eg. 1237cb960a2Sdownsj $ cat << ~michael 1247cb960a2Sdownsj ~michael 1257cb960a2Sdownsj $ 1267cb960a2Sdownsj works for pdksh, not for at&t ksh (POSIX seems to agree with pdksh). 1277cb960a2Sdownsj - in at&t ksh, tracked aliases have the export flag implicitly set 1287cb960a2Sdownsj and tracked aliases and normal aliases live in the same name space 1297cb960a2Sdownsj (eg, "alias" will list both tracked and normal aliases). 1307cb960a2Sdownsj in pdksh, -t does not imply -x (since -x doesn't do anything yet), and 1317cb960a2Sdownsj tracked/normal aliases live in seperate name spaces. 1327cb960a2Sdownsj in at&t ksh, alias accepts + options (eg, +x, +t) - pdksh does not. 1337cb960a2Sdownsj in pdksh, alias has a -d option to allow examination/changing of 1347cb960a2Sdownsj cached ~ entries, also unalias has -d and -t options (unalias -d 1357cb960a2Sdownsj is useful if the ~ cache gets out of date - not sure how at&t deals 1367cb960a2Sdownsj with this problem (it does cache ~ entries)). 1377cb960a2Sdownsj - at&t ksh will stop a recursive function after about 60 calls; pdksh 1387cb960a2Sdownsj will not since the limit is arbitrary and can't be controlled 1397cb960a2Sdownsj by the user (hit ^C if you get in trouble). 1407cb960a2Sdownsj - the wait command (with and without arguments) in at&t ksh will wait for 1417cb960a2Sdownsj stopped jobs when job control is enabled. pdksh doesn't. 1427cb960a2Sdownsj - at&t ksh automatically sets the bgnice option for interactive shells; 1437cb960a2Sdownsj pdksh does not. 1447cb960a2Sdownsj - in at&t ksh, "eval `false`; echo $?" prints 1, pdksh prints 0 (which 1457cb960a2Sdownsj is what POSIX says it should). Same goes for "wait `false`; echo $?". 1467cb960a2Sdownsj (same goes for "set `false`; echo $?" if posix option is set - some 1477cb960a2Sdownsj scripts that use the old getopt depend on this, so be careful about 1487cb960a2Sdownsj setting the posix option). 1497cb960a2Sdownsj - in at&t ksh, print -uX and read -uX are interrperted as -u with no 1507cb960a2Sdownsj argument (defaults to 1 and 0 respectively) and -X (which may or 1517cb960a2Sdownsj may not be a valid flag). In pdksh, -uX is interpreted as file 1527cb960a2Sdownsj descriptor X. 1537cb960a2Sdownsj - in at&t ksh, some signals (HUP, INT, QUIT) cause the read to exit, others 1547cb960a2Sdownsj (ie, everything else) do not. When it does cause exiting, anything read 1557cb960a2Sdownsj to that point is used (usually an empty line) and read returns with 0 1567cb960a2Sdownsj status. pdksh currently does similar things, but for TERM as well and 1577cb960a2Sdownsj the exit status is 128+<signal-number> - in future, pdksh's read will 1587cb960a2Sdownsj do this for all signals that are normally fatal as required by POSIX. 1597cb960a2Sdownsj (POSIX does not require the setting of variables to null so applications 1607cb960a2Sdownsj shouldn't rely on this). 1617cb960a2Sdownsj - in pdksh, ! substitution done before variable substitution; in at&t ksh 1627cb960a2Sdownsj it is done after substitution (and therefor may do ! substitutions on 1637cb960a2Sdownsj the result of variable substitutions). POSIX doesn't say which is to be 1647cb960a2Sdownsj done. 1657cb960a2Sdownsj - pwd: in at&t ksh, it ignores arguments; in pdksh, it complains when given 1667cb960a2Sdownsj arguments. 1677cb960a2Sdownsj - the at&t ksh does not do command substition on PS1, pdksh does. 168*dcacb757Sdownsj - ksh93 allows ". foo" to run the function foo if there is no file 169*dcacb757Sdownsj called foo (go figure). 170*dcacb757Sdownsj - field splitting (IFS): ksh88/ksh93 strip leading non-white space IFS 171*dcacb757Sdownsj chars, pdksh (and POSIX, I think) leave them intact. e.g. 172*dcacb757Sdownsj $ IFS="$IFS:"; read x; echo "<$x>" 173*dcacb757Sdownsj :: 174*dcacb757Sdownsj prints "<>" in at&t ksh, "<::>" in pdksh. 175*dcacb757Sdownsj - command completion: at&t ksh will do completion on a blank line (matching 176*dcacb757Sdownsj all commands), pdksh does not (as this isn't very useful - use * if 177*dcacb757Sdownsj you really want the list). 178*dcacb757Sdownsj - co-processes: if ksh93, the write portion of the co-process output is 179*dcacb757Sdownsj closed when the most recently started co-process exits. pdksh closes 180*dcacb757Sdownsj it when all the co-processes using it have exited. 1817cb960a2Sdownsj 1827cb960a2SdownsjOddities in ksh (pd & at&t): 1837cb960a2Sdownsj - array references inside (())/$(()) are strange: 1847cb960a2Sdownsj $(( x[2] )) does the expected, $(( $x[2] )) doesn't. 1857cb960a2Sdownsj - `typeset -R3 X='x '; echo "($X)"` produces ( x) - trailing 1867cb960a2Sdownsj spaces are stripped. 1877cb960a2Sdownsj - typeset -R turns off Z flag. 1887cb960a2Sdownsj - both shells have the following mis-feature: 1897cb960a2Sdownsj $ x='function xx { 1907cb960a2Sdownsj cat -n <<- EOF 1917cb960a2Sdownsj here we are in xx 1927cb960a2Sdownsj EOF 1937cb960a2Sdownsj }' 1947cb960a2Sdownsj $ (eval "$x"; (sleep 2; xx) & echo bye) 1957cb960a2Sdownsj [1] 1234 1967cb960a2Sdownsj bye 1977cb960a2Sdownsj $ xx: /tmp/sh1234.1: cannot open 1987cb960a2Sdownsj - bizarre special handling of alias/export/readonly/typeset arguments 1997cb960a2Sdownsj $ touch a=a; typeset a=[ab]; echo "$a" 2007cb960a2Sdownsj a=[ab] 2017cb960a2Sdownsj $ x=typeset; $x a=[ab]; echo "$a" 2027cb960a2Sdownsj a=a 2037cb960a2Sdownsj $ 2047cb960a2Sdownsj - both ignore SIGTSTP,SIGTTIN,SIGTTOU in exec'd processes when talking 2057cb960a2Sdownsj and not monitoring (at&t ksh kind of does this). Doesn't really make 2067cb960a2Sdownsj sense. 2077cb960a2Sdownsj (Note that ksh.att -ic 'set +m; check-sigs' shows TSTP et al aren't 2087cb960a2Sdownsj ignored, while ksh.att -ic 'set +m^J check-sigs' does... very strange) 2097cb960a2Sdownsj - when tracing (set -x), and a command's stderr is redirected, the trace 2107cb960a2Sdownsj output is also redirected. so "set -x; echo foo 2> /tmp/O > /dev/null" 2117cb960a2Sdownsj will create /tmp/foo with the lines "+ > /dev/null" and "+ echo foo". 2127cb960a2Sdownsj - undocumented at&t ksh feature: FPATH is searched after PATH if no 2137cb960a2Sdownsj executable is found, even if typeset -uf wasn't used. 2147cb960a2Sdownsj 2157cb960a2Sdownsjat&t ksh bugs: 2167cb960a2Sdownsj [various versions: 2177cb960a2Sdownsj MIPS m120 RISC/os 5.0: Version 11/16/88d 2187cb960a2Sdownsj Dec alpha osf/1 v1.3: OSF/1 Version 11/16/88d NLS 2197cb960a2Sdownsj HP pa HP-UX 9.01: Version 11/16/88 2207cb960a2Sdownsj ] 2217cb960a2Sdownsj - (only hpux) 2227cb960a2Sdownsj $ _[2]=hi 2237cb960a2Sdownsj Bus error (core dumped) 2247cb960a2Sdownsj - (only riscos, hpux) 2257cb960a2Sdownsj $ typeset x[ 2267cb960a2Sdownsj $ 2277cb960a2Sdownsj - (only osf/1) 2287cb960a2Sdownsj $ A=B cat << EOF 2297cb960a2Sdownsj .$A. 2307cb960a2Sdownsj EOF 2317cb960a2Sdownsj Segmentation fault(coredump) 2327cb960a2Sdownsj $ 2337cb960a2Sdownsj - (only osf/1) 2347cb960a2Sdownsj $ read "?foo " 2357cb960a2Sdownsj foo Foo 2367cb960a2Sdownsj $ set | grep Foo 2377cb960a2Sdownsj =Foo 2387cb960a2Sdownsj $ 2397cb960a2Sdownsj - (all) 2407cb960a2Sdownsj $ typeset -i A 2417cb960a2Sdownsj $ typeset -L3 A 2427cb960a2Sdownsj $ typeset -l A 2437cb960a2Sdownsj Illegal instruction (core dumped) 2447cb960a2Sdownsj - (all) 2457cb960a2Sdownsj $ for i in a b c ; do echo $i, ${i[2]}, ${i[10]} ; done 2467cb960a2Sdownsj a, , 2477cb960a2Sdownsj a, , b 2487cb960a2Sdownsj a, , c 2497cb960a2Sdownsj $ 2507cb960a2Sdownsj - (all) 2517cb960a2Sdownsj $ echo ${abc:-G { I } K } 2527cb960a2Sdownsj G { I K } 2537cb960a2Sdownsj $ 2547cb960a2Sdownsj $ abc=hi 2557cb960a2Sdownsj $ echo ${abc:-G { I } K } 2567cb960a2Sdownsj hi K } 2577cb960a2Sdownsj $ 2587cb960a2Sdownsj The second echo should only have printed `hi'. 2597cb960a2Sdownsj - (all) 2607cb960a2Sdownsj $ echo ${abc:- > foo} 2617cb960a2Sdownsj syntax error: > unexpected 2627cb960a2Sdownsj $ 2637cb960a2Sdownsj - (all? hpux) read reads too much from pipe (when pipe isn't stdin) 2647cb960a2Sdownsj print 'hi\nthere' | ksh 8<&0 0< /dev/tty 2657cb960a2Sdownsj $ read -u8 x 2667cb960a2Sdownsj $ print $x 2677cb960a2Sdownsj hi 2687cb960a2Sdownsj $ cat 0<&8 2697cb960a2Sdownsj $ read -u8 y 2707cb960a2Sdownsj $ print $y 2717cb960a2Sdownsj there 2727cb960a2Sdownsj $ 2737cb960a2Sdownsj - (all) 2747cb960a2Sdownsj $ umask 0 2757cb960a2Sdownsj $ umask 2767cb960a2Sdownsj 00 2777cb960a2Sdownsj $ 2787cb960a2Sdownsj - (osf, mips, !hpux) 2797cb960a2Sdownsj $ exec alias 2807cb960a2Sdownsj alias: not found 2817cb960a2Sdownsj (shell dead) 2827cb960a2Sdownsj - (all) non-white space IFS in non-substitution not preserved 2837cb960a2Sdownsj $ IFS="$IFS:" 2847cb960a2Sdownsj $ echo : "$@" # this is ok 2857cb960a2Sdownsj : 2867cb960a2Sdownsj $ echo :"$@" # this should print : too (me thinks) 2877cb960a2Sdownsj 2887cb960a2Sdownsj $ 2897cb960a2Sdownsj - (only osf/1) 2907cb960a2Sdownsj $ set +m 2917cb960a2Sdownsj $ sleep 1 & # wait for a sec or two 2927cb960a2Sdownsj $ jobs 2937cb960a2Sdownsj Memory fault (core dumped) 2947cb960a2Sdownsj - (all) 2957cb960a2Sdownsj $ (sleep 1 & echo hi) & 2967cb960a2Sdownsj [1] 123 2977cb960a2Sdownsj $ [1] 234 2987cb960a2Sdownsj hi 2997cb960a2Sdownsj - (osf/1, mips) 3007cb960a2Sdownsj $ getopts abc optc -a -b -c 3017cb960a2Sdownsj $ getopts abc optc -a -b -c 3027cb960a2Sdownsj $ getopts abc optc -a 3037cb960a2Sdownsj Memory fault (core dumped) 3047cb960a2Sdownsj - (osf/1) POSIX says OPTIND shall be initialized to 1 3057cb960a2Sdownsj $ echo $OPTIND 3067cb960a2Sdownsj 0 3077cb960a2Sdownsj $ 3087cb960a2Sdownsj - (osf/1 + others?) 3097cb960a2Sdownsj $ typeset -ri r=10 3107cb960a2Sdownsj $ let r=12 3117cb960a2Sdownsj $ echo $r 3127cb960a2Sdownsj 12 3137cb960a2Sdownsj $ 3147cb960a2Sdownsj - (osf/1 + others?) 3157cb960a2Sdownsj $ typeset -i a 3167cb960a2Sdownsj $ typeset -L3 a 3177cb960a2Sdownsj Memory fault (core dumped) 3187cb960a2Sdownsj - (osf/1 + others?): -L strips leading \ \t\n\r, -R only strips trailing 3197cb960a2Sdownsj spaces 3207cb960a2Sdownsj $ typeset -L3 x 3217cb960a2Sdownsj $ x=' ^I^J^M 2' 3227cb960a2Sdownsj $ echo "($x)" 3237cb960a2Sdownsj (2 ) 3247cb960a2Sdownsj $ typeset -R3 y 3257cb960a2Sdownsj $ x='2^I^J^M ' 3267cb960a2Sdownsj $ echo "($x)" 3277cb960a2Sdownsj (^I^J^M) 3287cb960a2Sdownsj $ 3297cb960a2Sdownsj - (osf/1 + others?) 3307cb960a2Sdownsj $ typeset +i RANDOM 3317cb960a2Sdownsj Memory fault (core dumped) 3327cb960a2Sdownsj - (osf/1 + others?): -L/-R/-Z clear -l/-u after assignment and vise versa 3337cb960a2Sdownsj $ typeset -u x=ab 3347cb960a2Sdownsj $ echo "($x)" 3357cb960a2Sdownsj (AB) 3367cb960a2Sdownsj $ typeset -L4 x=def 3377cb960a2Sdownsj $ echo "($x)" 3387cb960a2Sdownsj (DEF ) 3397cb960a2Sdownsj $ typeset | grep ' x$' 3407cb960a2Sdownsj leftjust 4 x 3417cb960a2Sdownsj $ 3427cb960a2Sdownsj $ typeset -L4 x=def 3437cb960a2Sdownsj $ echo "($x)" 3447cb960a2Sdownsj (def ) 3457cb960a2Sdownsj $ typeset -u x=ab 3467cb960a2Sdownsj $ echo "($x)" 3477cb960a2Sdownsj (AB ) 3487cb960a2Sdownsj $ typeset | grep ' x$' 3497cb960a2Sdownsj uppercase x 3507cb960a2Sdownsj $ 3517cb960a2Sdownsj $ typeset -i x 3527cb960a2Sdownsj $ x='2()' 3537cb960a2Sdownsj $ x='()' 3547cb960a2Sdownsj $ x='2(4)' 3557cb960a2Sdownsj - (osf/1, others?) 3567cb960a2Sdownsj $ unset foo 3577cb960a2Sdownsj $ echo "${foo:-"*"}" 3587cb960a2Sdownsj <results of * expansion> 3597cb960a2Sdownsj $ 3607cb960a2Sdownsj - (osf/1, others?) 3617cb960a2Sdownsj $ alias blah 3627cb960a2Sdownsj blah: alias not found 3637cb960a2Sdownsj $ alias -x blah | grep blah 3647cb960a2Sdownsj blah 3657cb960a2Sdownsj $ type blah 3667cb960a2Sdownsj Memory fault (core dumped) 3677cb960a2Sdownsj - (osf/1, others?) 3687cb960a2Sdownsj $ trap 'echo hi; false' ERR 3697cb960a2Sdownsj $ false 3707cb960a2Sdownsj hi 3717cb960a2Sdownsj hi 3727cb960a2Sdownsj .... 3737cb960a2Sdownsj Memory fault (core dumped) 3747cb960a2Sdownsj - (osf/1, others?) 3757cb960a2Sdownsj $ typeset +i ERRNO 3767cb960a2Sdownsj Memory fault (core dumped) 3777cb960a2Sdownsj - (osf/1, others?) 3787cb960a2Sdownsj $ X=abcdef 3797cb960a2Sdownsj $ echo ${X#a{b,c}e} # does not match {} inside word part of ${..#..} 3807cb960a2Sdownsj abcdefe} 3817cb960a2Sdownsj $ 3827cb960a2Sdownsj - (osf/1, others?) 3837cb960a2Sdownsj $ x=f=abcdef 3847cb960a2Sdownsj $ echo ${f#a|abc} 3857cb960a2Sdownsj def 3867cb960a2Sdownsj $ echo ${f#abc|a} 3877cb960a2Sdownsj bcdef 3887cb960a2Sdownsj $ echo ${f#abc|a|d} 3897cb960a2Sdownsj abcdef 3907cb960a2Sdownsj $ 3917cb960a2Sdownsj - (osf/1, hp-ux, others?) 3927cb960a2Sdownsj $ i() echo hi 3937cb960a2Sdownsj $ typeset -f 3947cb960a2Sdownsj function i 3957cb960a2Sdownsj { 3967cb960a2Sdownsj hi 3977cb960a2Sdownsj $ 3987cb960a2Sdownsj - (osf/1, others?) 3997cb960a2Sdownsj $ function X { 4007cb960a2Sdownsj echo start of X 4017cb960a2Sdownsj function Y { 4027cb960a2Sdownsj echo in Y 4037cb960a2Sdownsj } 4047cb960a2Sdownsj echo end of X 4057cb960a2Sdownsj } 4067cb960a2Sdownsj $ X 4077cb960a2Sdownsj start of X 4087cb960a2Sdownsj end of X 4097cb960a2Sdownsj $ typeset -f 4107cb960a2Sdownsj function X 4117cb960a2Sdownsj { 4127cb960a2Sdownsj echo start of X 4137cb960a2Sdownsj function Y { 4147cb960a2Sdownsj echo in Y 4157cb960a2Sdownsj } 4167cb960a2Sdownsj echo end of X 4177cb960a2Sdownsj } 4187cb960a2Sdownsj function Y 4197cb960a2Sdownsj { 4207cb960a2Sdownsj echo in Y 4217cb960a2Sdownsj echo end of X 4227cb960a2Sdownsj } 4237cb960a2Sdownsj } 4247cb960a2Sdownsj $ 4257cb960a2Sdownsj - (osf/1, others?) 4267cb960a2Sdownsj $ while read x; do print -r "A $x"; done |& 4277cb960a2Sdownsj [1] 18212 4287cb960a2Sdownsj $ exec 8<&p 4297cb960a2Sdownsj $ kill %1 4307cb960a2Sdownsj Memory fault 4317cb960a2Sdownsj - (osf/1, others?) Error only happens for builtin commands (/bin/echo works) 4327cb960a2Sdownsj $ while read x; do print -r "A $x"; done |& 4337cb960a2Sdownsj [1] 18212 4347cb960a2Sdownsj $ echo hi <&p 4357cb960a2Sdownsj hi 4367cb960a2Sdownsj $ echo hi <&p 4377cb960a2Sdownsj ksh: p: bad file unit number 4387cb960a2Sdownsj $ while read x; do print -r "A $x"; done |& 4397cb960a2Sdownsj ksh: process already exists 4407cb960a2Sdownsj $ 4417cb960a2Sdownsj - (osf/1, others?) in restricted shells, command -p should not work. 4427cb960a2Sdownsj $ PATH=/tmp ksh -r 4437cb960a2Sdownsj $ print hi | command -p cat -n 4447cb960a2Sdownsj 1 hi 4457cb960a2Sdownsj $ 4467cb960a2Sdownsj - (osf/1, others?) error message wrong for autoload files that don't define 4477cb960a2Sdownsj functions 4487cb960a2Sdownsj $ FPATH=/tmp 4497cb960a2Sdownsj $ echo echo hi there > /tmp/aja 4507cb960a2Sdownsj $ aja 4517cb960a2Sdownsj hi there 4527cb960a2Sdownsj ksh: echo: not found 4537cb960a2Sdownsj $ 4547cb960a2Sdownsj 4557cb960a2SdownsjPOSIX sh questions (references are to POSIX 1003.2-1992) 4567cb960a2Sdownsj - arithmetic expressions: how are empty expressions treated? 4577cb960a2Sdownsj (eg, echo $(( ))). at&t ksh (and now pdksh) echo 0. 4587cb960a2Sdownsj Same question goes for `test "" -eq 0' - does this generate an error 4597cb960a2Sdownsj or, if not, what is the exit code? 4607cb960a2Sdownsj - should tilde expansion occur after :'s in the word part of ${..=..}? 4617cb960a2Sdownsj (me thinks it should) 4627cb960a2Sdownsj - if a signal is received during the execution of a built-in, 4637cb960a2Sdownsj does the builtin command exit or the whole shell? 4647cb960a2Sdownsj - is it legal to execute last command of pipeline in current 4657cb960a2Sdownsj execution environment (eg, can "echo foo | read bar" set 4667cb960a2Sdownsj bar?) 4677cb960a2Sdownsj - what action should be taken if there is an error doing a dup due 4687cb960a2Sdownsj to system limits (eg, not enough feil destriptors): is this 4697cb960a2Sdownsj a "redirection error" (in which case a script will exit iff the 4707cb960a2Sdownsj error occured while executing a special built-in)? 4717cb960a2Sdownsj IMHO, shell should exit script. Couldn't find a blanket statement 4727cb960a2Sdownsj like "if shell encounters an unexpected system error, it shall 4737cb960a2Sdownsj exit non-interactive scripts"... 4747cb960a2Sdownsj 4757cb960a2SdownsjPOSIX sh bugs (references are to POSIX 1003.2-1992) 4767cb960a2Sdownsj - in vi insert mode, ^W deletes to beginning of line or to the first 4777cb960a2Sdownsj blank/punct character (para at line 9124, section 3). This means 4787cb960a2Sdownsj "foo ^W" will do nothing. This is inconsistent with the vi 4797cb960a2Sdownsj spec, which says delete preceding word including and interceding 4807cb960a2Sdownsj blanks (para at line 5189, section 5). 4817cb960a2Sdownsj - parameter expansion, section 3.6.2, line 391: `in each case that a 4827cb960a2Sdownsj value of word is needed (..), word shall be subjected to tilde 4837cb960a2Sdownsj expansion, parameter expansion, ...'. Various expansions should not 4847cb960a2Sdownsj be performed if parameter is in double quotes. 4857cb960a2Sdownsj - the getopts description says assigning OPTIND a value other than 1 4867cb960a2Sdownsj produces undefined results, while the rationale for getopts suggests 4877cb960a2Sdownsj saving/restoring the OPTIND value inside functions (since POSIX 4887cb960a2Sdownsj functions don't do the save/restore automatically). Restoring 4897cb960a2Sdownsj OPTIND is kind of dumb since getopts may have been in the middle 4907cb960a2Sdownsj of parsing a group of flags (eg, -abc). 4917cb960a2Sdownsj - unclear whether arithmetic expressions (eg, $((..))) should 4927cb960a2Sdownsj understand C integer constants (ie, 0x123, 0177). at&t ksh doesn't 4937cb960a2Sdownsj and neither does pdksh. 4947cb960a2Sdownsj - `...` definition (3.6.3) says nothing about backslash followed by 4957cb960a2Sdownsj a newline, which sh and at&t ksh strip out completely. e.g., 4967cb960a2Sdownsj $ show-args `echo 'X 4977cb960a2Sdownsj Y'` 4987cb960a2Sdownsj Number of args: 1 4997cb960a2Sdownsj 1: <XY> 5007cb960a2Sdownsj $ 5017cb960a2Sdownsj POSIX would indicate the backslash-newline would be preserved. 5027cb960a2Sdownsj - does not say how "cat << ''" is to be treated (illegal, read 'til 5037cb960a2Sdownsj blank line, or read 'til eof). at&t ksh reads til eof, bourne shell 5047cb960a2Sdownsj reads 'til blank line. pdksh reads 'til blank line. 505