Why does sudo ignore aliases?

I see the below information from here.

When using sudo, use alias expansion (otherwise sudo ignores your aliases)

alias sudo='sudo '

The reason why it doesn't work is explained here.

Bash only checks the first word of a command for an alias, any words after that are not checked. That means in a command like sudo ll, only the first word (sudo) is checked by bash for an alias, ll is ignored. We can tell bash to check the next word after the alias (i.e sudo) by adding a space to the end of the alias value.


Aliases and functions are defined in a shell. Sudo is an external program. So sudo doesn't see aliases, functions or shell builtins, only external commands.

Aliases are meant to be alternate command names, so shells only expand them in command position, not when they're arguments to commands. Zsh supports global aliases, which are expanded anywhere on the command line, and best use sparingly since there is a risk of accidentally expanding them even in contexts where the alias doesn't make sense.

You can tell sudo to invoke a shell: sudo sh -c '…shell command here…'. Your usual aliases won't be available inside that shell command, however, since they're normally stored in a file such as ~/.bashrc or ~/.zshrc which is only read by interactive shells.

alias sudo='sudo ', as proposed by Ramesh, causes the shell to expand aliases after sudo.


A solution for zsh users

In both bash and zsh, ending an alias with a space will cause the shell to alias-expand the next word. This allows something like the following to alias expand myalias

alias 'sudo=sudo '
sudo myalias

Unfortunately this falls apart when you have more then one word in your alias (like sudo -u someone. However you can abuse the zsh "global aliases" feature to manually expand aliases anywhere in the command.

alias -g '$= '

This creates a global alias called $ (you can use any word you want) which ends in a space. This causes zsh to expand the next word as a regular command alias. Since the alias expands to whitespace it won't be treated as an argument. This allows the following to work.

% alias myalias=echo
% sudo -u someone myalias foo
sudo: myalias: command not found
% sudo -u someone $ myalias foo
foo

You can even use $ multiple times on one command line if you have complicated command nesting. I've found this useful enough that it has a permanent place in my zshrc, however the alias is simple enough to define when you need to use it.

Tags:

Shell

Alias

Sudo