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