Technical notes › Use ‘sudo’ with aliases in fish
Something that’s slightly annoying on the command-line is that sudo
only works with executable binaries, and cannot know about shell aliases.
I have a bunch of ls
-related aliases, like these:
alias l 'exa' alias ls 'exa' alias ll 'exa --long --git --header' alias la 'exa -a --long --git --header'
(As mentioned in Make fish start faster by avoiding alias
, they are actually functions rather than aliases, but the effect is the same for both.)
I’ve been writing ll
instead of ls -l
for so long now that I instinctively try to use it with sudo
as well.
However, sudo has no idea that it exists, because it’s an alias, rather than a file in the $PATH
it can execute.
This means that whenever I try to run this command using sudo, instead of a long file listing, I see this:
sudo ll
sudo: ll: command not found
I deal with this by having a fish wrapper function that runs the output through a sub-fish if it’s a function.
The ‘sudo’ fish wrapper
I have this function defined, which is also called sudo
:
functions/sudo.fish
function sudo -d "sudo wrapper that handles aliases" if functions -q -- $argv[1] set -l new_args (string join ' ' -- (string escape -- $argv)) set argv fish -c "$new_args" end command sudo $argv end
It works by testing if the command that sudo is going to run — the first argument — is a defined function or fish alias, and if it is, it runs a new temporary fish session through sudo instead. The command that gets run looks like this:
sudo fish -c 'll'
The fish
that gets run under sudo
reads my list of aliases before running the command, so when it tries to execute ll
, it’ll run the contents of the alias with root privileges.
Some notes about how this is implemented:
- The uses of the
string
built-in are there to properly escape spaces before the function arguments get handed to the temporary fish process. Because this process takes two arguments (‘-c
’ and a line of shell script to run) we need to take care when combining multiple arguments into one single string. - We need to run the result though
command
to stop the wrapper function from recursing and calling itself. - Finally, we need the ‘
--
’ meta-argument before the calls tofunctions
andstring
to stop arguments to the program being run under sudo being treated as arguments to thefunctions
orstring
built-ins themselves.
The function above is an improved version of one given in an answer to this Stack Overflow question. That one has issues with arguments containing spaces; the function on this page has that issue fixed.∎