Date: Tue, 1 Feb 2022 10:23:53 -0500 From: Chet Ramey <chet.ra...@case.edu> Message-ID: <1e33f111-b9ff-2d70-adf8-934906321...@case.edu>
| Historically, bash (and ksh93) has favored the former. Just about all the | other shells claiming some sort of POSIX conformance favor the latter (all | the ash-based shells, yash, mksh). For ash bashed shells, at least, that's because the text in the command substitution is not parsed twice - it is parsed (nb: just parsed, not expanded or evaluated) once while scanning it to find the closing ')', and the results of that parse are simply kept for later when it is to be used. Since it isn't possible for anything to change the command substitution text once scanning it has started, the results of a parse of its text done later must be the same as that done while scanning (that is, no commands can possibly be executed between when that scan starts, and when the command substitution is later expanded, assuming it ever is) so doing the parse all over again is something of a waste of time. Since the command substitution might never be expanded however, some bookkeeping is needed to make sure that the resulting parse tree is discarded if it isn't used - but compared to the work needed for an additional parse, that's trivial. But if you're sure that the double parse method is needed, the simple fix would be to save original command substitution text, not the alias expanded form of it, in the word being constructed, and simply continue to expand the alias both times (as above, since no commands can get executed between the first and second parse, assuming the 2nd happens, the alias cannot be altered, and it will expand the 2nd time the same way it did the first). It seems to me that the way you're doing it now would also break: alias x=y cat <<$(x) whatever $(x) which is supposed to work, and indeed, in the bash 5.2 development branch, it does (the terminator after the here-doc text needs to be $(y) to work). kre