Martijn Dekker <[email protected]> wrote:
> I've been in correspondence with a few people who still seem to believe
> that AT&T ksh88 is POSIX compliant because POSIX was originally based on
> ksh88. On Solaris, to this day, /usr/xpg4/bin/sh is ksh88 and is
> considered "the POSIX compliant shell".
Maybe it is important that Solaris did AFAIK only check against SUSv6.
BTW: ksh93 is not POSIX compliant, so the question is whether there is any
really POSIX compliant shell implementation...
> /usr/xpg4/bin/sh on Solaris 11.3 has at least the following bugs. The
> list is not exhaustive; this is just what I've discovered while
> developing modernish. The IDs here are those from modernish's shell
> bug/quirk/feature testing framework. FTL_* are considered "fatal" shell
> bugs that will normally cause modernish to refuse to initialise.
>
> * FTL_ASGNBIERR: Variable assignments preceding regular builtin commands
> should not persist after the command exits, but with this bug they do if
> the builtin exits with an error. This may break scripts in obscure ways.
> For example, 'LC_ALL=C test a -wrong b' causes the LC_ALL assignment to
> persist, so your locale settings are gone. Even more havoc may be
> wreaked with a similar temporary assignment to PATH...
The original Bourne Shell did longjmp() / exit() for all builtins in such a
case. I would guess this is the result of an incomplete transition.
> * FTL_BRACSQBR: a bracket glob pattern containing a quoted closing
> square bracket ']' is never matched, not even if that character is
> escaped or passed from a quoted variable. For example,
> case ] in [a\]b] ) echo ok;; * ) echo bug;; esac
> case a in [a\]b] ) echo ok;; * ) echo bug;; esac
> case b in [a\]b] ) echo ok;; * ) echo bug;; esac
> all output 'bug'.
This looks like a ksh88 specific bug. It works correctly even with the historic
BOurne Shell.
> * FTL_COMMAND2P: double parsing of parameter expansion when using
> 'command' with an external command. For example,
> a=\$x
> x=bug
> command printf '%s\n' "$a"
> prints 'bug'. Clearly, this makes the 'command' builtin unusable.
Isn't "command" a POSIX invention? I guess there are too few tests in te POSIX
test suite.
> * FTL_NOFNOVER: ksh88 does not allow you to override a regular shell
> builtins with a shell function. POSIX specifies that only special
> builtins can't be overridden with shell functions, and all other shells
> allow overriding regular builtins.
Is this true for SUSv1 already?
> * FTL_PARONEARG: When IFS is empty (i.e. field splitting is off), "$@"
> is counted as a single argument instead of each positional parameter as
> separate arguments. In other words, "$@" does not *generate* fields when
> field *splitting* is disabled (which is of course illogical and POSIX
> has rightly fixed this).
When did POSIX fix this and is there a related test in the test suite?
> * FTL_UNSETFAIL: the 'unset' command sets a non-zero exit status if the
> variable to unset was not already set, whereas POSIX says: "Unsetting a
> variable or function that was not previously set shall not be considered
> an error [...]"
> This can cause spurious non-zero exit statuses for functions that end in
> an 'unset' command to clean up internal variables. (In itself this is
> easy to work around; modernish only considers this bug fatal because all
> existing shells that have this bug have other fatal errors as well.)
Since this does not apply to the Bourne Shell, it looks like a ksh specific bug.
> * FTL_UPP: Cannot access "$@" or "$*" if set -u (-o nounset) is active
> and there are no positional parameters. If that option is set, ksh88
> errors out on accessing "$@" and "$*". This makes 'set -u' impractical
> to use, so POSIX changed this from ksh88, rendering "$@" and "$*" exempt
> from 'set -u'.
This problem exists in the Bourne Shell already. It may have been changed in
POSIX without createin a related test.
> * BUG_ARITHINIT: Using unset or empty variables in arithmetic
> expressions causes the shell to error out with a "bad number" error.
> Instead, according to POSIX, it should take them as a value of zero.
This looks like the first deviation between POSIX and ksh88.
> * BUG_CMDPV: More 'command' builtin breakage: the -p and -v options
> cannot be combined, so you can't query the location of the command
> within the default system PATH.
See my command comment above...
> * BUG_HDPARQUOT: Quotes within parameter substitutions in Here-Documents
> aren't removed. For instance, if 'var' is set, ${var+"x"} in a here-
> document erroneously yields "x", not x.
This is Bourne Shell and ksh88 behavior.
If this was changed in POSIX recently, it is a problem with the test suite, if
it was never changed in POSIX, this is a POSIX decription bug.
> * BUG_PP_08: When IFS is null, unquoted $* within a substitution (e.g.
> ${1+$*} or ${var-$*}) does not generate one field for each positional
> parameter as expected, but instead joins them into a single field.
See parameter expansion above.
> * BUG_PSUBBKSL: A backslash-escaped character within a quoted parameter
> substitution is not unescaped, e.g.
> echo "${foo-\x}"
> outputs '\x' instead of 'x'.
See parameter expansion above.
>
> P.S. Not that it's very relevant anymore, but for completeness's sake:
> /usr/bin/ksh on Solaris 10.1 (non-sh ksh88, which was replaced by ksh93
> on Solaris 11) has the following bugs as well:
>
> * FTL_NOARITH: incomplete and buggy support for POSIX shell arithmetic.
> Particularly, octal numbers by leading zero such as $((010 == 8)) are
They are supported by /usr/xpg4/bin/sh and they never have been supported by
/usr/bin/ksh, even when it still was ksh88 based.
> not supported. There are other bugs as well, like:
> x=42
> echo $(( (y=x)==0x2A ))
> results in "0x2A: bad number", which is clearly wrong, because
> echo $(( (y=42)==0x2A ))
> works.
Works with /usr/xpg4/bin/sh and ksh93, but did never work with a vanilla ksh88.
> * BUG_CSCMTQUOT: unbalanced single and double quotes and backticks in
> comments within $(command substitutions) cause obscure and hard-to-trace
> syntax errors later on in the script. Example:
> echo $(echo one # this won't work
> echo two )
> spuriously parses the "'" in the comment as shell grammar, causing an
> unmatched quote error that may or may not show up as such, depending on
> the script.
ksh88 counts quotes and brackets instead of using a recursive parser that is
needed for 100% $(cmd) support.
> * BUG_CSNHDBKSL: Backslashes within non-expanding here-documents (that
> is, with quoted end-of-document delimiters) within command substitutions
> are incorrectly expanded to perform newline joining, as opposed to left
> intact. For example,
>
> echo "$(cat <<'EOF'
> abc
> def \
> ghi
> EOF
> )"
>
> outputs:
>
> abc
> def ghi
>
> instead of:
>
> abc
> def \
> ghi
This may be a result of the way the parser is implemented.
Jörg
--
EMail:[email protected] (home) Jörg Schilling D-13353 Berlin
[email protected] (work) Blog: http://schily.blogspot.com/
URL: http://cdrecord.org/private/ http://sf.net/projects/schilytools/files/'