Bash Alias - Precedence/Shadowing (/hiding/failing)

Bash does allow aliases to contain aliases but it has built-in protections against infinite loops. In your case, when you type lsc, bash first expands the alias to:

ls -Flatr --color=always

Since ls is also an alias, bash expands it to:

lsc -Flatr --color=always

lsc is an alias but, quite sensibly, bash refuses to expand it a second time. If there was a program named lsc, bash would run it. But, there is not and that is why you get command not found.

Addendum

It is different when lscR runs. lscR expands to:

ls -FlatrR --color=always

Since ls is an alias, this expands to:

lsc -FlatrR --color=always

Since lsc is an alias, this expands to:

ls -Flatr --color=always -FlatrR --color=always

Since ls has already been expanded once, bash refuses to expand it a second time. Since a real command called ls exists, it is run.

History

As noted by Schily in the comments, bash borrowed the concept of not expanding an alias a second time from ksh.

Aside

Aliases are useful but not very powerful. If you are tempted to do something complex with an alias, such as argument substitution, don't; use a shell function instead.


From the bash manual:

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.

In the ls alias, ls is expanded to lsc and then again to ls -Flatr --color=always, and there the alias expansion stops, since ls was originally being expanded. So, the command runs fine, ls now being resolved to an external command.

In the lsc alias, lsc is expanded to ls -Flatr --color=always, and then ls is now expanded to lsc and there the alias expansion stops, since lsc was originally being expanded. So, the command fails, since bash doesn't know of any other lsc.

Tags:

Bash