On Fri, 2022-01-28 at 09:51 +0000, Geoff Clare via austin-group-l at
The Open Group wrote:
> > result="$(command ; e=$?; print '.' ; exit $?)"
>
> The print should be printf, and I assume you intended exit $e here.
Of course... sorry,... shouldn't write such things late in the night ^^
> Also, having carefully arranged the exit
> status you want, you don't do anything with it.
That I don't understand?
> Personally I would use:
>
> result="$(some_command && printf '.')" || exit
I don't think this works properly... or better said:
It seems to assume, that the result is only wanted/valid when
some_command succeeds (only then the sentinel would be printed and
result be valid).
[Plus if printf would fail there, while command still succeeded one
wouldn't now what actually happened (did the printf fail? did some
command fail?)]
But one can easily imagine commands, where the stdout would still be
valid, despite the exit status being non-zero.
What about:
result="$(some_command ; e=$?; print '.' && exit $e || exit 666 )"
With 666 being really one of:
- 127 or
maybe 126
POSIX already uses these in e.g. nohup or time
"utility was found but could not be invoked"
"utility could not be found"
but utility here, would rather be some_command... so the codes might
be misleading.
- GNU "defines" e.g.:
EXIT_TIMEDOUT 124 job timed out
EXIT_CANCELED 125 internal error
EXIT_CANNOT_INVOKE 126 error executing job
EXIT_ENOENT 127 couldn't find job to exec
of which 125 seems to fit nicely.
> > #optionally error out if OLD_LC_ALL is already set
> > unset -v OLD_LC_ALL ; [ "${LC_ALL+is_set}" ] &&
> > OLD_LC_ALL="${LC_ALL}"
> >
> > LC_ALL=C
> > result="${result%.}"
> >
> > [ "${OLD_LC_ALL+is_set}" ] && LC_ALL="${OLD_LC_ALL}" || unset -v
> > LC_ALL
>
> You should unset -v OLD_LC_ALL here.
You mean at the end for clean up? Well I thought that would have been
clear to the reader ;-)
But you're right of course.
> I don't think an explicit statement about it needs to be added, but
> there is scope for improving the current wording so it is clearer
> what is intended. E.g. change:
>
> ... replacing the command substitution (...) with the standard
> output of the command(s), removing sequences of one or more
> <newline> characters at the end of the substitution. Embedded
> <newline> characters before the end of the output shall not be
> removed; however, they may be treated as field delimiters ...
>
> to:
>
> ... replacing the command substitution (...) with the standard
> output of the command(s); if the output ends with one or more
> bytes that have the encoded value of a <newline> character, they
> shall not be included in the replacement. Any such bytes that
> occur elsewhere shall be included in the replacement; however,
> they might be treated as field delimiters ...
Seems to perfectly clarify it. (And already give it a meaning of bytes
;-) ).
Are you going to take care of it or should I make a request for it?
> > b) What shell variables are actually required to be able to hold?
> > Any
> > bytes except NUL ... vs. any valid character in the locale, except
> > NUL.
>
> It seems from the discussion that the requirement for environment
> variables to contain characters may be accidental. If so, that
> should
> be fixed. As a knock-on this would confirm there is no restriction
> (beyond no-NUL-bytes) on shell variables since they are initialised
> from environment variables.
Same here... are you taking care... or should I file a request?
> > c) Something that might have come up[0], namely whether
> > setting/unsetting/assigning LANG/LC_* needs to have an immediate
> > effect
> > on the shell (script/interactive session).
> > E.g. the LC_ALL=C ; var="${var%.}"
> > Is that "voluntary" or mandated.
>
> I think that was discussed before during the work we did on shell
> parsing, but I don't remember the details.
Ok.. I'll try to find it in the archives.
Thanks,
Chris