Closed treinen closed 6 years ago
As I understand the standard, only command words of simple comands shall be candidates for alias substitution. That is, in my opinion, in a script like this
alias foreach=for foreach x in a b c; do ....; done
the foreach should not be replaced as it is part of a complex command, not a simple command. OTOH, dash does make this replacment. Maybe the explanation is that the alias substitution shall happen before applying any grammatical rules?
How can we know that it is indeed a complex command? Do you think that the alias substitution should happen after the promotion from word to reserved word?
This issue seems fixed to me by the following implementation of alias_substitution
.
(** [alias_substitution aliases checkpoint word] substitutes an
alias by its definition if word is not a reserved word and
if the parsing context is about to reduce a [cmd_name]. *)
let alias_substitution aliases checkpoint word =
if about_to_reduce_cmd_name checkpoint then (
if not (Keyword.is_reserved_word word) then
substitute aliases word
else
word
) else word
The Posix standard says:
... resulting word that is identified to be the command name word of a simple command shall be examined to determine whether it is an unquoted, valid alias name ...
In my understanding (which may be wrong) this means that only a WORD which is obtained through this sub-derivation
simple_command -> cmd_name -> WORD
or maybe as the first WORD in
simple_command -> cmd_name cmd_suffix -> WORD cmd_suffix
can be candidate for alias substitution. How these can be found before applying any grammar rules, as the standard requires, escapes me but that is a different matter.
For instance, the following shell script
alias show=echo show show
should print "show", and "not "echo" . Dash does this right, but when you look at the json produced by morbig you see that it has in fact replaced both occurrences of "show".
The same error occurs on toplevel-unalias.sh in the tests/good directory: If you look at the json produced by morbig you see that the unalias has not been executed. The reason for this is that the first alias has also replaced the argument of the succeeding unalias, making it ineffective.