xref: /openbsd/bin/ksh/NOTES (revision dcacb757)
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