231

I was playing around with aliases today and I noticed that aliases don't seem to be available whilst using sudo:

danny@kaon:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

danny@kaon:~$ ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //

danny@kaon:~$ sudo -i
root@kaon:~# ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //
root@kaon:~# exit
logout

danny@kaon:~$ sudo ll -d /
sudo: ll: command not found

Is there any reason why you cannot use aliases whilst using sudo?

4

8 Answers 8

385

Add the following line to your ~/.bashrc:

alias sudo='sudo '

From the bash manual:

Aliases allow a string to be substituted for a word when it is used as the first word of a simple command. The shell maintains a list of aliases that may be set and unset with the alias and unalias builtin commands.

The first word of each simple command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The characters ‘/’, ‘$’, ‘`’, ‘=’ and any of the shell metacharacters or quoting characters listed above may not appear in an alias name. The replacement text may contain any valid shell input, including shell metacharacters. 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. If the last character of the alias value is a space or tab character, then the next command word following the alias is also checked for alias expansion.

(Emphasis mine).
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.

14
  • 35
    Pretty nice solution.
    – ulidtko
    Jan 17, 2011 at 23:23
  • 2
    The emphasized quote doesn't show up too well with askubuntu.com's current styling. For the curious, here is the key line: "If the last character of the alias value is a space or tab character, then the next command word following the alias is also checked for alias expansion." Feb 7, 2015 at 11:15
  • 4
    Reading the documentation obviously benefits a whole lot :-) Feb 10, 2016 at 20:48
  • 11
    Will this break if I use a sudo flag, e.g. sudo -H ll? Apr 9, 2016 at 5:19
  • 4
    @mehaase Yes, I tried and it breaks.
    – user31389
    Mar 10, 2017 at 21:57
6

I wrote a Bash function for it that shadows sudo.

It checks whether I have an alias for the given command and runs the aliased command instead of the literal one with sudo in that case.

Here is my function as one-liner:

sudo() { if alias "$1" &> /dev/null ; then $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}" ; else command sudo $@ ; fi }

Or nicely formatted:

sudo() { 
    if alias "$1" &> /dev/null ; then 
        $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}"
    else 
        command sudo "$@"
    fi 
}

You can append it to your .bashrc file, don't forget to source it or restart your terminal session afterwards to apply the changes though.

1
  • It would be wonderful if this would also work for sudo -H ll.
    – uav
    Nov 20, 2018 at 19:00
4

The aliases are user specific - you need to define them in /root/.bashrc

3
  • 4
    They are already under /root/.bashrc so that's not an issue
    – kemra102
    Jan 18, 2011 at 20:55
  • 5
    This answer would only be correct for the situation when you're running the shell itself as root, as with sudo -s or sudo -i (and only if run by itself to get a root shell, not with the sudo -s command... or sudo -i command... forms) or sudo bash or sudo su, or the situation where you've enabled root logins and have a root shell that way. When a non-root user runs sudo command... from their own shell, alias expansion is done by their own non-root shell. sudo doesn't itself expand aliases, so as applied to the situation described in the question, this answer is incorrect. Sep 17, 2017 at 7:31
  • I confirm @kemra102: I do have my root aliases in place. su ll not a problem. sudo ll failures.
    – Frank N
    Apr 17, 2021 at 7:36
4

@Alvins answer is the shortest one. No doubt! :-)

However I thought of a command line solution to execute an aliased command in sudo where there is no need to redefine sudo with an alias command.

Here is my proposal for those to whom it may interest:

Solution

type -a <YOUR COMMAND HERE> | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Example

In the case of the ll command

type -a ll | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Explanation

when you have an alias (such as: ll) the command type -a returns the aliased expression:

$type -a ll
ll is aliased to `ls -l'

with grep you select the text between the accent ` and apostrophe ' in that case ls -l

And xargs executes the selected text ls -l as parameter of sudo.

Yes, a bit longer but completely clean ;-) No need to redefine sudo as alias.

4
  • 4
    Might be simpler if you used the alias builtin, since its output is cleaner. alias ll outputs alias ll='ls -ahlF'.
    – muru
    Feb 15, 2015 at 19:41
  • Here's the version incorporating @muru's suggestion: alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo. Jul 27, 2016 at 17:07
  • I think the point of the original question was to save work by not having to sudo -i first, to run the aliased command, but doing it straight away. Having such a complex command defeats that. You could just do the former, and be much quicker.
    – anon
    Sep 8, 2017 at 15:13
  • Which answer was by @Alvins? I can't find it and it isn't refernced.
    – Cadoiz
    Feb 16, 2023 at 8:51
2

I have another nice solution, that adds a bit of trust too:

Use bash completion to automatically replace words behind sudo with their aliases when pressing tab.

Save this as /etc/bash_completion.d/sudo-alias.bashcomp, and it should automatically be loaded at interactive shell startup:

_comp_sudo_alias() { from="$2"; COMPREPLY=()
  if [[ $COMP_CWORD == 1 ]]; then
    COMPREPLY=( "$( alias -p | grep "^ *alias $from=" | sed -r "s/^ *alias [^=]+='(.*)'$/\1/" )" )
    return 0
  fi
  return 1
}
complete -o bashdefault -o default -F _comp_sudo_alias sudo

Then log in to a new terminal, and you should be good to go.

2
  • There's a way to get a list of aliases, especially meant for completion: compgen -a
    – muru
    Sep 8, 2017 at 17:04
  • @muru: Thanks, but in this case I need the values, not the keys. So what the alias that was entered will be replaced with. You type the alias, (like in sudo ll), press [TAB ↹], and the script finds ll in the list of alias assignments , cuts out what it is assigned to it, and inserts that. (So you’d get e.g. sudo ls -lahvF --color=auto --time-style=long-iso.)
    – anon
    Sep 9, 2017 at 1:29
2

@WinEunuuchs2Unix: $PWD expands to the "present working directory". I think you want $HOME.

Also, for most situations, it's probably best to have a separate root .bashrc file. In fact, I'd make it a real file in /root, soft link to it in the user's home directory (e.g., .bashrc_root), and source it from the user's .bashrc file. If at some later time this privileged user account is no longer present, the root .bashrc file is still available for other users.

1

If you type sudo -i and elevate to a sudo prompt (#) you won't have the aliases or functions you like to use.

To utilize your aliases and functions at the # prompt, use:

sudo cp "$HOME"/.bashrc /root/.bashrc

Where "$HOME" is expanded into "/home/YOUR_USER_NAME"

2
  • @DKBose Thanks for catching that for me :) Jan 11, 2020 at 19:11
  • Attention! This overwrites your /root/.bashrc (obv.) - and thus might add a whole bunch of other side effects.
    – Cadoiz
    Feb 16, 2023 at 8:53
0

I have a different solution whereby you do not need to add sudo as an alias. I run Linux Mint 17.3 but it should be pretty similar to Ubuntu.

When you are root, then the .profile is run from its home directory. If you do not know what the home directory under root is, then you can check with:

sudo su
echo $HOME

As you can see, the home of root is /root/. Check its contents:

cd $HOME
ls -al

There should be a .profile file. Open the file and add the following lines:

if [ "$BASH" ]; then
    if [ -f ~/.bash_aliases];then
        . ~/.bash_aliases 
    fi
fi

Basically, what this bash script does is to check for a file called .bash_aliases. If the files is present, it executes the file.

Save the .profile file and create your aliases in .bash_aliases. If you already have the aliases file ready, then copy the file to this location

Re-launch the terminal and you are good to go!

1
  • 1
    You can just symlink your aliases for root user with sudo ln -s /home/$(whoami)/.bash_aliases /root/.bash_aliases just to keep a single version. However, this answer only enables aliases if you are within root shell (i.e. sudo -i), but not if you invoke a command with sudo yourownalias. This is because Bash does not load root profile when sudo command is invoked.
    – igor
    Aug 16, 2023 at 12:04

You must log in to answer this question.

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