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?