Email List: Xaustin-group-lX
[All Lists]

Enhancement request: SUS bootstrapping procedure for shell scripts

To: austin-group-l@xxxxxxxxxxxxx
Subject: Enhancement request: SUS bootstrapping procedure for shell scripts
From: Wayne Pollock <pollock@xxxxxxx>
Date: Wed, 05 Aug 2009 20:28:15 -0400
There is no way to guarantee a SUS/POSIX shell
and environment.  This is not a problem for
interactive use, as a user of some system can
manually bootstrap this environment, usually by
executing a POSIX shell and using
   PATH=$(getconf PATH)

This is also not an issue when booting a computer;
the shell scripts that are used for that on most
POSIX (okay I really mean Unix/Linux) systems need
not be and in some cases aren't POSIX compliant.
A compliant environment can't be guaranteed until
a system is fully "up".

There remains one common case I would like to see
addressed: that of a shell script.  Since the
"she-bang" line is not part of SUS (and I guess won't
be any time soon), the only reference is this excerpt
from the SUS "exec" function:

<quote>
... In the cases where the other members of the exec family
of functions would fail and set errno to [ENOEXEC], the
execlp() and execvp() functions shall execute a command
interpreter and the environment of the executed command shall
be as if the process invoked the sh utility using execl()
as follows:

execl(<shell path>, arg0, file, arg1, ..., (char *)0);

where <shell path> is an unspecified pathname for the
sh utility, ...
</quote>

To me this implies a POSIX/SUS shell but that isn't
always the case, say with Solaris in which "/bin/sh"
is not POSIX compliant but is the default shell
started. (Although OpenSolaris uses the Korn shell AFAIK).

Without endorsing a she-bang standard I think the SUS could
still include a way to get a script to run with a compliant
environment including a POSIX shell.  Without any additional
support the best I can come up with so far is this:

<SSCCE>
PATH=$(getconf PATH)
tail -n +4 "$0" | sh -
exit
# Script starts here
printf 'Hello, World!\n'
</SSCCE>

(See <http://www.sscce.org/> for the meaning of SSCCE.)

This should work *providing* the default environment
includes a compliant version of getconf, but I'm
not proud of this code.

What I'd like to see is the execlp and execvp system
calls be enhanced to include something like this:

<quote>
... On any compliant system, a supplied process image file
pathname of ``/bin/SUS-POSIX'' shall execute a command
interpreter and the environment of the executed command
shall be as if the process invoked the sh utility using
execl() as follows ...
</quote>

The idea is that this pathname need not exist but a
simple and useful idea would be to have a (link to a)
compliant shell with that pathname.  On systems without
such a filesystem the execlp and execvp would need to
start a POSIX shell and not some arbitrary shell, when
supplied with that string.

This would permit compliant systems work as always and
require no changes save for the addition of a symlink
to the filesystem.  (``ln -s /bin/ksh /bin/SUS-POSIX'')
But on systems that do use a she-bang mechanism, you
could then force a compliant environment for a script
by:

<SSCCE>
#!/bin/SUS-POSIX -
PATH=$(getconf PATH)
printf 'I am running a POSIX shell and using SUS utilities!\n'
</SSCCE>

Note I really don't care what special pathname is used.
``/bin/SUS'' or something else might be nicer but I would
worry about the potential conflict with some real file
at such a pathname.

To have this guaranteed to work under a POSIX shell you
need one further change:  getconf should behave as if it
were a built-in utility in a POSIX shell.  It need not
be built-in, and on (say) a Solaris, Cygwin, Gnu/Linux
system there is only one getconf anyway; so such a requirement
is no burden and should require no changes.  But, if
PATH were not set to use a SUS version of getconf, this
requirement would cause it to use that.  (An example
implementation shows this to be trivial: have the shell
add an alias to the correct getconf if needed.)

I think this would be a useful way to allow portable
shell scripts while imposing minimal (or no) changes to
most current POSIX/SUS OSes, and should not cause any
backward compatibility issues.

It has been suggested to me that the special pathname
should include a version number, e.g. ``/bin/SUSv4-POSIX'',
but then you need the complication that without the
version number, the most recent version of the standard(s)
should apply.  That way when SUSv6 breaks compatibility with
SUSv5 someday, a SUSv5 script would still work provided
such an environment was still available.  I believe Solaris
does something like that with /usr/xpg[46]/bin directories.

I realize the reluctance of the Austin Group to put in
enhancements.  I guess you see your goal as to document
and clarify existing practice, and to resolve ambiguities
and conflicts.  But I also know occasionally enhancements
can be made, especially if they involve small but useful
changes.

-- 
Wayne Pollock

<Prev in Thread] Current Thread [Next in Thread>