tech-userlevel archive

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

Re: bin/47597: local and $() don't play well with each other



    Date:        Tue, 26 Feb 2013 12:48:10 +0000 (UTC)
    From:        uwe%stderr.spb.ru@localhost (Valeriy E. Ushakov)
    Message-ID:  <kgiaua$e6q$1%ger.gmane.org@localhost>

  | is that passage in SUS about
  |     foo=xxx f           # (1)
  |     export var=value    # (2)

It's about (1).   But you have to read all the guff about variable
assignments (as they use the term) to be certain of that.

There's no real question about that for the paragraph in 2.14,
and if reinforcement is needed, consider the example given for the ':'
command (the "null utility") (which is one of the special built-in commands) ...

    As with any of the special built-ins, the null utility can also
    have variable assignments and redirections associated with it, such as:

    x=y : > z

    which sets variable x to the value y (so that it persists after the
    null utility completes) and creates or truncates file z.

The relevant part of that for us here is the "so it persists" part, which
is just reinforcing the rule in 2.14.

For what it is worth, I have no problem with this treatment of special
built-in commands - in general there's no point giving them variable
assignments anyway, as none of them use the values of any variables...

That is, except for one, which causes SUS to say something patently absurd,
which as best I can tell no shell implements.

That is

        foo=xxx unset foo

should, according to 2.14 (since unset is a special built-in) result in
foo retaining the value xxx after the special built-in comletes.   But
that would be wacky to say the least (and this is the one case where a
var assign on a special built-in actually makes sense - it is not an error
to unset a variable that is not set, but it does result in a non-zero
exit code) - if the script is run with set -e, then if a variable which
might not be set is to be unset, one must do either

        unset foo || true
or
        foo= unset foo

and (personally) I think the latter is cleaner.   But it doesn't work if
the letter of the SUS is obeyed (fortunately, it is not...)

Personally, I would have just made var assignments on special built-ins have
undefined effect.  That would have been cleaner and caused less problems.
There's no need to have persistent var assignments with special built-ins,
if one wants to do what the example above of the : comamnd is doing,
one can just do

        x=y; : > z

instead (or leave out the : completely in most cases).

kre




Home | Main Index | Thread Index | Old Index