Date: Thu, 11 Apr 2024 11:05:43 +0200 From: Philipp Lengauer <p.lenga...@gmail.com> Message-ID: <CAFJdOf65G9XShQ7VKSu8yp2+QtzOBwZeq=rnusm45n15nvp...@mail.gmail.com>
| When defining aliases and then exporting a function uses these aliases, the | exported function body has the aliases expanded. This makes sense because | we cannot be sure the same aliases exist in the child process where the | exported function will eventually be used. That's not the reason it happens though - it happens because aliases (which are an obnoxious idea, rarely really work the way you'd like them to - as here - and should be avoided completely) are expanded as the input is read (they're a lexical construct) when one is detected at the appropriate position. ie: when you do: alias echo='echo PREFIX' echo hello world what the lexical analyser hands to the parser is: alias echo='echo PREFIX' echo PREFIX hello world But if you were to write E= $E echo hello world then the alias wouldn't be expanded ("echo" is not in the command word position when the lexical analyser runs, $E is - when later run, $E vanishes (as E is empty) and the echo command is run, but by then it is way too late for aliases to affect anything. Aliases are stupid! | However, when using subshells in | the child process, the aliases are not expanded. I think you'll find they are. Where they're not expanded is in command substitutions (in bash anyway) - as (bash) doesn't parse those until they're executed (well, to be strict, they're parsed twice, once just to locate their end, and the results are discarded, and then again when they're used). Since aliases aren't exported, (which I hope never changes - or more importantly, that there is never a way to allow aliases to be imported) when the shell parses the command substitution (in the shell environment which has imported it) the environment has no alias, so obviously it cannot work as you expected. You'd see the same thing if your function was foo() { eval "echo 'hello world'"; } as again, the eval string is parsed only when it is executed (and for eval, unlike the command substitution example, this is important) and if you export the foo function, the "echo" being in a string isn't expanded as an alias. Nor should it be. (It would be if you ran this version in a shell which has an alias for echo defined.) | This is unexpected behavior and potentially breaks the function. Using aliases tends to break things. There's never a really good (sane) reason to do so, just don't do that. Instead of alias echo='echo PREFIX' just do echo() { command echo PREFIX "$@"; } (and export that if that's what you need). kre