TL;DR: You can use sudo -i
to run a function defined /root/.bashrc
(but not an alias) and also have access to variables exported from that file:
sudo -i command arguments
Aliases don't work there, though, but you can easily convert them to functions if you'd like to make them available to sudo -i
.
Read on for full analysis and more details.
There are a few problems here, some in how sudo works and some in how bash itself works...
By default, sudo
will only look for commands and will bypass the shell, so simply running sudo ll
will only work if there's an ll
executable in one of the directories in $PATH
. So, in order to use aliases (or functions) you need to make sure a shell is invoked as part of the process.
One way would be to run something like sudo sh
or sudo bash
, though modern sudo
(I'm testing this on sudo 1.8.19p1) has options -s
and -i
for that purpose.
So one try would be something like sudo -s ll
(which is equivalent to sudo bash -c 'll'
, assuming your $SHELL
is Bash, which seems to be the case based on the rcfile
you mentioned.) But that doesn't work either, since it starts the shell in a non-interactive, non-login mode, which doesn't read any of its startup files. It's essentially the same as if you write a shell script and use #!/bin/bash
to run it. The aliases (and functions) you have in your ~/.bashrc
won't be accessible from that script...
So next is the -i
option, which creates a login shell. That's more promising, since it will read your startup files! And yet, sudo -i ll
(equivalent to sudo bash -l -c 'll'
) will still not work. So how is that possible, given it did read the definition of the ll
alias?
Well, the next explanation here is that, by default, bash will not expand aliases, except when the shell is interactive... This shell started by sudo -i
(or bash -l
) is a login shell, but still not interactive.
So the next step is to get an interactive shell, which then works:
sudo bash -i -c 'll'
(Having both login and interactive is also fine, of course, bash -l -i -c ...
will work.)
Another alternative is to keep using a login shell (non-interactive) but ask it explicitly to expand aliases, so this will also work:
sudo bash -l -O expand_aliases -c 'll'
(The case where bash was interactive didn't need a login shell, since that is enough to read the initialization files, but this one needs -l
to read them.)
These are fairly long command lines... And they also require that you quote the whole shell command, so if you're calling an alias with arguments, you'll have to turn all that into a string... So it's kind of clumsy to use...
Note that earlier I was talking about aliases and functions... That was on purpose, since functions are actually a lot more convenient here. You don't need anything special (such as having an interactive shell, or setting a specific option) to execute functions on a shell, as long as you're sourcing their definition.
So if you defined ll
as a function instead of an alias, you'd be able to use it directly with sudo's -i
shortcut:
sudo -i ll
And if you have a longer command-line, with arguments, you could pass them directly here too:
sudo -i ll -C -R /etc
(Compare to sudo bash -i -c 'll -C -R /etc'
.)
Functions are also a lot more flexible and typically easier to maintain... It's usually easy to convert an alias into a function, the only caveat is to always use "$@"
where you'd expect extra arguments to be taken (typically at the end of the alias.)
For example, this alias:
alias ll='ls $LS_OPTIONS -l'
Could be turned into this function:
ll () {
ls $LS_OPTIONS -l "$@"
}
They are, for most purposes, equivalent. And, as mentioned before, the function should be accessible directly from sudo -i
, so that's an added bonus.
I hope you find this answer and explanation helpful!
/root/.bashrc
but really what the Q is after is the aliases from this file - this is not possible per this - https://unix.stackexchange.com/questions/1496/why-doesnt-my-bash-script-recognize-aliases. – slm Jul 26 '18 at 14:01-r
option forcrontab
:crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}
. This works when logged in as either user, however when I executesudo crontab -r
it still executes. – Daniel Gelling Jul 26 '18 at 14:32