tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Unanticipated /bin/sh change a few weeks ago
It has been brought to my attention (off list) that the change to
the way that the ! command (reserved word) is permitted to be used
in /bin/sh has affected one use case that wasn't anticipated - that is,
the possibility never occurred to me.
That is defining a function as
func() ! simple_command
no longer works, though we still permit
func() simple_command
(Both of which are non-standard extensions to the POSIX sh definition.)
The change happened because we actually permit
func() command
and one of the possibilities for "command" is "simple_command" and
simple_command (used to) permit a leading ! reserved word, and does
not any more.
! is now only permitted in (at the start of) a pipeline, which in normal
use is the only place it makes sense (and is what the standard defines)
and a pipeline is not one of the elements of a command (rather a command is
one of the elements of a pipeline.)
I see four possibilities to deal with this...
1. leave it as it is now,
func() ! simple_command
is non-standard usage,
func() { ! simple_command; }
works, and is standard (works everywhere).
2. Change the definition of a function definition (in our sh) from
name "()" command
to
name "()" pipeline
which would automatically permit the "! simple_command" case,
and would also permit
func() ls | wc -l
and similar. It would make it harder to include a function definition
in a pipeline however, and that is a standard blessed use case, not that
it is a useful endeavour (definitions do not read or write anything, so
defining a function with stdin or stdout redirected from/to some other
command isn't really useful - and what's more isn't guaranteed to work
anyway, as pipelines are permitted to be executed in sub-shells, and if
they were, the function definition, if embedded in a pipeline, would never
become visible in the shell.)
If we go this route, we could instead permit and_or (instead of command
or pipeline) - though I have not thought through the implications of that
one. Going all the way and allowing a list would break too much I suspect.
[ and_or would allow "func() command && other" to be a definition, rather
than meaning "if the definition succeeds (they always do) run "other",
Allowing "list" would mean "func() command; command & command" would
all be a definition - but in that case, I suspect the definition would
continue growing until EOF, there would be nothing to stop it, where
"EOF" here includes the end of some embedding syntax element, if any.
]
3. Change the definition of a function definition (in our sh) to
name "()" [ "!" ] command
which would put back the functionality that was removed - and a little
more, as that would also permit
func() ! { command; command...; }
and similar. This one has least effect (of any change) upon the
language the shell implements, but would be one more hack...
If we did this we might actually want to make it
name "()" [ "!" [ "!" ] ] command
for consistency with what we allow in pipelines (again, non-standard.)
4. Put back BOGUS_NOT_COMMAND (allowing ! in bizarre places) or perhaps
just in the (still bizarre) case in simple_command.
This one I would really prefer if we not do.
Which of those do people think best? Does anyone (else) use the
func() ! command
method of defining a function?
kre
ps: none of this has anything at all to do with using a function after it
is defined. For that a function is just one case of a simple_command.
Home |
Main Index |
Thread Index |
Old Index