0

Bash manual says

The first word of the replacement text is tested for aliases, but a word that is identical to an alias being expanded is not expanded a second time. This means that one may alias ls to ls -F, for instance, and Bash does not try to recursively expand the replacement text.

I'm trying to figure out which alias follows "identical to" in the quote,

  • any alias being expanded in the same sequence of alias expansion recursions, or

  • the alias whose expansion was first started, or

  • the alias whose expansion was last started.

So I create an example

$ alias a1=a2; 
$ alias a2=a3;
$ alias a3=a4;

and want to check the alias expansion result of a1, in the following cases

$ alias a4=a1;

or

$ alias a4=a2;

or

$ alias a4=a3;

How can I check the alias expansion result of a1, possibly by performing alias expansion on a1 without letting the shell going further than alias expansion?

1
  • I'm not sure I entirely grok the question but my interpretation is just that, for a1=..., when literal a1 itself is encountered in the alias definition it is simply ignored (until the next step of command resolution/execution)... and no matter how many nested levels deep it's encountered.
    – B Layer
    Commented Aug 5, 2017 at 19:26

2 Answers 2

5

What the manual says is that the shell will avoid any loop that may be caused by recursion of alias expansion.

With your example (a1=a2=a3=a4), if you execute alias a4=a1 you are creating a loop. Then, as soon as you will execute a1 (resp. a2, a3, a4), once the shell loops back to a1 (resp. a2, a3, a4) it will search for a command named a1 (resp. a2, a3, a4) that is NOT an alias (since that would create a never-ending loop).

Example:

$ a1() { echo Phew, I got out of the loop; }
$ alias a1='echo "(a1)"; a2' a2='echo "(a2)"; a3'
$ alias a3='echo "(a3)"; a4' a4='echo "(a4)"; a1'

$ a1
(a1)
(a2)
(a3)
(a4)
Phew, I got out of the loop

$ a2                              # Command a2 does not exist anywhere
(a2)
(a3)
(a4)
(a1)
a2: command not found
4
  • Thanks. When I change a4='echo "(a4)"; a1' to a4='echo "(a4)"; a2', running a1 doesn't output anything. Wondering why...
    – Tim
    Commented Aug 5, 2017 at 21:08
  • @Tim On my system (bash 4.3), doing so gives an output that is roughly similar to my second example.
    – xhienne
    Commented Aug 5, 2017 at 21:12
  • Thanks. I got your result in a new terminal. Maybe something is messed up in the original terminal.
    – Tim
    Commented Aug 5, 2017 at 21:16
  • Brilliant illustration. Wow.
    – Wildcard
    Commented Aug 9, 2017 at 2:18
1
:> alias e="echo "
:> alias text=foo
:> e text
foo

Technically the shell does go further than alias expansion but nonetheless I think this is what you meant.

1
  • 1
    @ADDB Unfortunately you think wrong. And it would have been easy for you to try it out before posting, wouldn't it? alias echo="echo foo" ; alias e=echo ; e Commented Aug 5, 2017 at 20:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .