bug-bash
[Top][All Lists]
Advanced

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

Re: Enable compgen even when programmable completions are not available?


From: Robert Elz
Subject: Re: Enable compgen even when programmable completions are not available?
Date: Tue, 27 Jun 2023 02:23:23 +0700

    Date:        Mon, 26 Jun 2023 10:32:19 +0100
    From:        Kerin Millar <kfm@plushkava.net>
    Message-ID:  <20230626103219.0f74c089c616248cee6ab51b@plushkava.net>


  | Further, declare is granted special treatment, even after having been
  | defined as a function (which might be a bug).

That will be because of the way that "declaration" utilities (which get
special syntax rules for parsing their args) are detected.   POSIX allows
(and I think most shells which implement that absurd idea, for this there
is very little choice) those to be detected merely by examining the
characters that make up the command word, well before any actual
interpretation of them is attempted.

In bash, "declare" (the built-in) is a a declaration utility, so its
args always get special treatment by the parser, regardless of whether
or not the declare that will be run is the declaration utility, or
something else (eg: a function).

In POSIX, this is not a problem, as the declaration utilities are all
special built-in commands, and those are recognised before functions
(ie: it is not meaningfully possible to define a function to replace
a special built-in).   Bash, at least in non-posix mode, doesn't have
that restriction.

Avoiding the declaration utility nonsense arg parsing semantics if
desired is easy, all that's needed is something like

        E=
        $E declare ...

and then since "$E" is the command word position, and is not a
declaration utility (regardless of what E is set to, an alternative
that does the same thing is:

        D=declare
        $D ...

as "$D" is not a declaration utility either - before it is expanded).

Both of them run "declare" with the args processed in the same way
that would be used for any other utility (like echo, printf, or awk).

Unfortunately, it can be (fractionally) simpler to write code where
the magic declaration utility parsing rules are used, though as best
I can tell it is never the only way - to avoid it, one simply needs
to separate the declaration from the assignment, putting one before
the other (which order depends upon the declaration utility, for export
it doesn't matter, either order works, for readonly the assignment
must appear before the readonly, for declare the declaration probably
usually needs to precede the assignment).   Simple variable assignments
(as distinct from things which appear to be variable assignments but
which are actually just args to a utility, regardless of what that
utility does with them) are always processed with the special arg
processing syntax rules.

Of course, none of this is relevant to finding a solution to the
original problem - but is to deciding whether or not the way that
bash gives special treatment to "declare" is a bug or not.   My
impression is that it is not, and that if an application (ie: you)
decide to define a function with the same name as a declaration
utility, you need to understand that it is still going to get
declaration utility arg parsing applied to it, rather than what
happens to everything else.

Of course, Chet might decide to change that - shells aren't
required to only use the chars that make up the command word
position (before anything is expanded) in order to determine
the expansion rules - another way (much more complex to code,
and probably slower to execute) would be the expand the words
in a simple command, one by one, finding the (expanded) word
which will actually be the command that is run, and then
parsing and expanding (in POSIX it is only expanding that
matters - the parsing rules do not alter, as posix has no arrays
and hence '(' is always an operator, never just a part of a
variable value) the remainder of the command line according to
the rules appropriate for the command that will actually be run.
Of course, if that were done, the trivial mechanisms to avoid
declaration utility semantics being applied given above ($E or $D)
no longer work.   But separating the declaration from the
assignment should always be possible - if it isn't, something is
going badly wrong (it might sometimes mean 3 commands need to be
executed instead of one - one declaration before the assignment,
and another after, but that's OK for more rational and understandable
syntax).

kre




reply via email to

[Prev in Thread] Current Thread [Next in Thread]