On Sat, May 24, 2025, at 4:47 PM, Greg Wooledge wrote: > On Sat, May 24, 2025 at 15:00:21 -0500, Bob Mroczka wrote: >> #!/bin/bash >> set -o pipefail >> shopt -s expand_aliases >> alias ub='echo hi' >> echo "alias ub='echo bye'" >~/.alias >> cat ~/.alias >> source ~/.alias && ub >> ub > > I believe you've run into the issue described in this paragraph of > the man page: > > The rules concerning the definition and use of aliases are somewhat > confusing. Bash always reads at least one complete line of input, and > all lines that make up a compound command, before executing any of the > commands on that line or the compound command. Aliases are expanded > when a command is read, not when it is executed. Therefore, an alias > definition appearing on the same line as another command does not take > effect until the next line of input is read.
And note that this behavior arises whenever you define and use an alias on the same line or in the same complex command; `source' is a red herring. Other shells exhibit the same behavior, and POSIX requires it [*]. % cat /tmp/aliases.sh alias ub='echo hi' alias ub='echo bye'; ub % bash -O expand_aliases /tmp/aliases.sh hi % dash /tmp/aliases.sh hi % ksh /tmp/aliases.sh hi % mksh /tmp/aliases.sh hi % oksh /tmp/aliases.sh hi % yash /tmp/aliases.sh hi % zsh /tmp/aliases.sh hi The usual workaround is to use a function instead. Another is to use `eval'. % cat /tmp/aliases_eval.sh alias ub='echo hi' alias ub='echo bye'; eval ub % bash -O expand_aliases /tmp/aliases_eval.sh bye % dash /tmp/aliases_eval.sh bye % ksh /tmp/aliases_eval.sh bye % mksh /tmp/aliases_eval.sh bye % oksh /tmp/aliases_eval.sh bye % yash /tmp/aliases_eval.sh bye % zsh /tmp/aliases_eval.sh bye [*] https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/V3_chap02.html#tag_19_03_01 -- vq