tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: RFC: Enhancements/changes to sh doc and a possible sh extension



    Date:        Wed, 18 Oct 2017 18:08:50 +0000
    From:        David Holland <dholland-tech%netbsd.org@localhost>
    Message-ID:  <20171018180850.GA16137%netbsd.org@localhost>

  | After chewing on it, what I think I'd like to see for builtins and
  | multiple shells is something like:
  | 
  |    - a page cd.1 that documents the basic behavior common to all shells(*)
  |    - pages of the form cd-sh.1 or cd-csh.1 that document shell-specific
  |      behavior, if there's more than say one paragraph of it
  |    - all of which should be clear on the command being a builtin, and
  |      why, unlike the current cd(1)

Yes, that all seems reasonable.

  | I don't think a new section (or a new suffix, which is slowly sorting
  | out to be comparable to a new section) is necessary or even really a
  | good idea, because the sections are basically namespaces.

Good, didn't think much of that idea.   But it did need mentioning.

  | Since the special builtins are more like syntax than commands, yes.

The one in particular that is big enough for a man page of its own, and
is not syntax pretending to be a command, is "set" - but that one is so
tightly bound to sh(1)'s option processing (as in the command line) that
moving it out is not practical.

The only ones that it might be possible/reasonable to move (unset, export
and readonly) aren't really big enough to matter.   "local" is probably
best considered a special built-in, and it might be worth extracting, but
it is not posix, so who knows what category it will be put in if it is
added, and in any case, is closer to syntax than the others here.

  | When/if I have time to work on anything again I'm happy to work on doc
  | cleanup like this :-)

Good, particularly since it has been so long since I last used csh, or
could even find a good reason for it to continue to exist, I am unlikely
to contribute much useful towards documenting it...

The nice thing about this project is that it can be done, one command
(or man page) at a time, there's no need that everything appear at once.

  | I think this is good functionality to have, but unless it already
  | exists elsewhere under -n,

It does, as the message said, in bash - that's where I got that choice from.

  | I wonder if there isn't a better name for it.

Before I saw it in bash, I had thought of using -a ("any", rather than
"all"), but -n isn't so bad, just think of it as "en-ee" ...)

If I had to guess, and that is all this is, I might suspect that bash
did not use "-a" precisely because that is more likely to be considered
as an "all" abbreviation rather than "any".  In "any" once the "a" is
eliminated as a viable choice, the 'n' comes next...   It doesn't hurt
that the same argument can be made if you think the long name of the option
should be "one" rather than "any" where the 'o' would not be a good choice
as you said, again leaving the 'n' as the next choice.   (Once again, pure 
speculation on my part - I didn't bother to ask.  It has been in bash for
long enough now that it isn't going to change there, so there was no
point.)

  | I at least would expect -n to provide access to WNOHANG (which is
  | certainly useful for scripts, IMO...) and this to be something else.

As I suggested in the ps right at the end of the mail, I think WNOHANG
would be better done (perhaps sometime in the future, not right now)
as "-t timeout" with a 0 timeout giving the pure WNOHANG.
(Not now, as that one is not trivial to add, unlike the WNOWAIT type
option I suggested, which is.)

  | I guess the optimum would be to have "wait" wait for one process and
  | "wait -a" to wait for all processes, but it's too late for that.

Yes, about 40 years (more probably).

  | And -1 is probably bad for other reasons, and -o doesn't suggest "once"
  | but "output". So I don't actually have a suggestion, just a vague
  | dissatisfaction. :-(

I would prefer not to be different just for the sake of it, so for this,
if we do it at all, I think we should stick to -n

  | When I first read this [the -p option description] I thought it was
  | returning argv[0] from the target job. On a second reading I thought
  | it was returning the pid.   Now I'm just confused about what it's doing.

I did say the doc was still WIP...   I will find a way to make it better.

If it gets written as a separate man page, rather than attempted to be
shoehorned into sh(1) - which is where the extract I quoted came from, then
it will be much easier to be more precise - in sh(1) there is a huge desire
to not bloat the doc any more than is absolutely required.   This is exactly
why I went back to the separate man pages for built-ins discussion...

But it is (more or less) the pid it is returning.  That's why 'p'.

With the most likely use:

	wait -n -p var

it is the pid (the exact same value that $! contained when the process/job
that exited was created) and I'd guess that scripts would, where possible,
actually use "pid" as the variable name, ie: "wait -n -p pid" and then
look for $pid in its list of running processes, to find which one exited.

If it doesn't care, it wouldn't use the option at all, just "wait -n",
though the var also allows the script to tell the difference between the
"wait -n" setting $? to 127 because there are no remaining running processes,
and it setting $? to 127 because the processes that terminated did so
using "exit(127)" - in the former case $var would be unset, in the latter,
it will contain a pid.  It works the same way with "wait -p var 1234" (no -n)
if process 1234 does not exist (ie: is not a child of this shell), wait
returns 127 as its status.  It does the same if pid 1234 is/was a child,
and terminated with "exit(127)" - which is entirely possible, if it happens
to be a sub-shell or some other sh process - the var will contain "1234" in
the latter case, and be unset in the former, providing a workaround for
one troublesome aspect from the posix spec for wait.

This is why the var is specifically defined to be unset initially, and
then only set if the exit status is being provided from a specific process/job.
All the error cases result in var remaining unset.

The simple case

	wait -p var

is simply "unset -v var; wait" as nothing useful is returned in $? there's
no point in attempting to say which process it is not being returned from...
(This only happens because there's no point special casing the code to make
the -p option either an error, or to act differently, in this case that
no-one rational would ever use anyway.)

Where it differs slightly is when the command given is

	wait [-n] -p var A1 A2 A3 ...

There, the An operands can either be pids (values previously obtained from $!)
or they can be job specifiers (%1 %2 ..., or even %+ %% %-).  It seemed more
useful to me to have the variable set to the actual An string of the process
(or job) from which the status was returned, than to convert it to a pid
if it wasn't already.   We have the "jobid" command (in sh(1)) to convert
from %n form to pid (I have a couple of minor enhancements planned for that
one, but those are not worth discussing) but at least currently no easy way to
go back from a pid to the %n form.   So I thought that it would be better
to simply return the actual An string that the script used. If that's a pid,
then the pid comes back, if it is %2, then %2 comes back, this allows the
script (or user on the command line) to work with whatever notation makes
sense to them.  (It also doesn't hurt that it's actually easier, and requires
less code, to do it this way!)

kre

ps: Christos, saw your earlier reply too - I had managed to divert myself
from this stuff and onto a different issue, so I had not yet done anything
towards implementing a WNOWAIT type option, and I agree, that can be
left until it is needed - and yes, implementing it is easy (trivial) which
is partly why I thought I'd just do it (but it can be done any time as
you said.)



Home | Main Index | Thread Index | Old Index