On Thu, 11 Apr 2024, at 10:05 AM, Philipp Lengauer wrote: > Configuration Information [Automatically generated, do not change]: > Machine: x86_64 > OS: linux-gnu > Compiler: gcc > Compilation CFLAGS: -g -O2 -flto=auto -ffat-lto-objects -flto=auto > -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security > -Wall > uname output: Linux TAG009442498805 5.15.0-102-generic #112-Ubuntu SMP Tue > Mar 5 16:50:32 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux > Machine Type: x86_64-pc-linux-gnu > > Bash Version: 5.1 > Patch Level: 16 > Release Status: release > > Description: > > 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. However, when using subshells in > the child process, the aliases are not expanded. This is unexpected > behavior and potentially breaks the function. > > Repeat-By: > > # this is a minimal example showing where it works and where it doesnt work > alias echo='echo PREFIX' > echo hello world > # prints "PREFIX hello world" => OK
There, the alias is expanded because you are in an interactive shell - where the expand_aliases shell option is already enabled - and because it is the "first word of a simple command". > foo() { echo "hello world"; } Likewise. Further, the alias is expanded at the time of the function's declaration. $ declare -f foo foo () { echo PREFIX "hello world" } > export -f foo > bash -c 'foo' > # prints "PREFIX hello world" => OK > > foo() { output="$(echo "hello world")"; printf '%s\n' "$output"; } > export -f 'foo' > # prints "hello world" => NOT OK (PREFIX missing) There, the alias does not end up being expanded ... $ declare -f foo foo () { output="$(echo "hello world")"; printf '%s\n' "$output" } Given that aliases cannot be exported by way of the environment as functions can be, it ends up not working as you had anticipated. Even were it the case that they could be, you would still have needed to enable expand_aliases in the non-interactive shell. Notwithstanding, I tried declaring the same function in an interactive instance of dash and found that the alias within the command substitution does end up being expanded, which is in stark contrast to the behaviour of bash. $ ps -o comm= -p "$$" dash $ alias echo='echo PREFIX' $ foo() { output="$(echo "hello world")"; printf '%s\n' "$output"; } $ unalias echo $ echo ok ok $ foo PREFIX hello world The behaviour of dash seems more logical to me, though I am uncertain as to which shell is in the right. -- Kerin Millar