How can I get sudo commands to use the settings in /root/.bashrc

sudo runs an executable, not a shell command. So it doesn't know about aliases. If you run sudo ls, that's like sudo /bin/ls, it doesn't use any ls alias that you may have.

You can cause sudo ls to expand the alias by putting the following in your .bashrc:

alias sudo='sudo '

Note the trailing space — that tells the shell to continue alias expansion with the word that comes after sudo. Beware that expanding aliases after sudo may not always be a good idea, it depends what kinds of aliases you have.

Furthermore sudo removes most variables from the environment. This won't affect an alias like alias ls='ls $LS_OPTIONS', because that's a shell variable used by the shell while it's expanding the command (and exporting it from .bashrc serves no purpose). But it would affect variables that are used by the command, such as LS_COLORS. You can configure sudo to keep certain environment variables by editing its configuration: run visudo and add the line

Defaults env_keep += "LS_COLORS"

With these settings, sudo ll will give the colors you're used to.

Alternatively, you can run a root shell with sudo -s. This shell will load its configuration file (~/.bashrc for bash). Depending on how sudo is configured, this may keep HOME set to your home directory, or change it to /root. You can force the home directory to be set to root's with sudo -Hs; conversely, to keep the original home directory, run sudo env HOME="$HOME" bash.


Thanks to those who answered, who prompted me to read man sudo more carefully.

sudo -s If no command is specified, an interactive shell is executed.

This interactive shell uses /root/.bashrc and thus includes my customisations.

It does require the command be entered separately, but this is OK.


Background

I've always felt like this question is an XY problem. The title implies they want anything out of /root/.bashrc but really what the question is after is the aliases from this file - this is widely believed to not be possible per this - Why doesn't my Bash script recognize aliases?.

It's basically by design that your aliases will not get picked up in sudo and in other places because they're not portable, and this is my opinion on them as well.

Anything that's in the user's environment should not be assumed by scripts and any software that may run on a given box. But I realize that there are scenarios where there might be some aliases in a given user account's $HOME/.bashrc that others might want to leverage in interactive scenarios.

To that end you can simply tell the Bash interpreter to expand any aliases that it finds during the login process outside of the normal shell behaviors that you run into when using sudo.

Example

Setup

To set things up I've added the following aliases, environment variables, and functions to my root user's /root/.bashrc and /root/.bash_profile files.

$ grep smurf ~/.bashrc
alias brc_smurf='echo "ran alias from /root/.bashrc"'
export brc_smurf_env='var from /root/.bashrc'
bpf_smurf_func() { echo 'ran func from /root/.bash_profile'; }

$ grep smurf ~/.bash_profile
alias bpf_smurf='echo "ran alias from /root/.bash_profile"'
export bpf_smurf_env='var from /root/.bash_profile'
brc_smurf_func() { echo 'ran func from /root/.bashrc'; }

Without doing anything neither of these work (no surprises):

$ sudo brc_smurf
sudo: brc_smurf: command not found

$ sudo bpf_smurf
sudo: bpf_smurf: command not found

We see that the alias command shows no aliases when run in sudo:

$ sudo alias
$

This behavior is your hint that you shouldn't expect aliases to be accessible. But we carry on...

Step #1 - aliases visible

If we run bash -ci we can induce Bash to at least read our $HOME/.bashrc:

$ sudo bash -ci 'alias' | grep smurf
alias brc_smurf='echo "ran alias from /root/.bashrc"'

Cool, so maybe we can run it?

$ sudo bash -ci 'alias; brc_smurf'
bash: alias; brc_smurf: No such file or directory

Step #2 - shopt -s expand_aliases

Nope. Again this is by design, we're doing something we're not suppose to be doing, so there's a number of "safeties" that we have to disable. the other "safety" is Bash.

$ sudo bash -ci 'shopt -s expand_aliases; alias; brc_smurf'
alias brc_smurf='echo "ran alias from /root/.bashrc"'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
ran alias from /root/.bashrc

Here we can see our message from /root/.bashrc, we've successfully executed the root user's alias brc_smurf.

Step #3 - what about env vars?

If you're using the method shown above these should now work as well.

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env'
ran alias from /root/.bashrc
var from /root/.bashrc

Step #4 - what about functions?

These works too as expected:

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env;brc_smurf_func'
ran alias from /root/.bashrc
var from /root/.bashrc
ran func from /root/.bashrc

TLDR;

You can do this to get access to environment variables + aliases from /root/.bashrc:

$ sudo bash -ci 'shopt -s expand_aliases; <cmds>'

Take aways

This method enables the contents of /root/.bashrc, it does not pick up the contents of /root/.bash_profile.

References

  • What is the XY problem?
  • Why does sudo ignore aliases?
  • Why doesn't my Bash script recognize aliases?

Tags:

Bash

Sudo

Debian