I want to add two aliases, so one executes a command when non sudo, and the other executes a command when sudo, like this:
alias v = 'nvim'
alias 'sudo v' = 'sudo -E nvim '
I also have set alias sudo='sudo '
.
I'm describing what to do in bash
. I don't know zsh
well enough to describe what to do there.
I think your problem is on the left side of the equal sign. Use a unique, short and easy to remember name for the alias (no spaces). Also there should be no spaces around the equal sign.
Otherwise it is easy to include sudo
into an alias, just put it in the definition of the alias. I can show an example from my aliases in ~/.bashrc
,
alias uc='sudo umount /dev/sdc*'
(to unmount all partitions on the drive /dev/sdc
)
I might have suggested sv
as the name of the alias, but there is a standard tool with that name, so maybe sev
, acronym for 'sudo -E nvim', will work better.
v
that does something, but they want sudo v
to do something slightly different.
If you have
alias sudo='sudo '
alias v='nvim'
then running sudo v whatever
would run sudo nvim whatever
, as the trailing space in the alias makes the shells look at the next word for alias expansion also.
But you can't have singular aliases with whitespace in their names: Bash doesn't accept it, and while zsh does, I don't think there's a way to actually use them:
zsh% alias 'a b'='echo test'
zsh% 'a b'
zsh: command not found: a b
$ alias 'a b'='echo test'
bash: alias: `a b': invalid alias name
As for adding that -E
option to sudo
, if you don't want to include that in the sudo
alias (i.e. alias sudo='sudo -E '
), then the closest options I can think of would be something like these:
alias sudoe='sudo -E '
alias v='nvim'
# or
alias sudov='sudo -E nvim'
Or as the comments suggest, use sudoedit
/ sudo -e
for editing files instead.
If you want to use that particular syntax, where v
is an alias for nvim
but sudo v
executes sudo -E nvim
(but you don't want -E
for all uses of sudo), you most likely to need to redefine sudo with a function.
Actually, it's not so tricky to define a function that treats v
differently. What is tricky is that you currently have alias sudo='sudo '
. I presume this is because you want to be able to use another of your aliases for the sudo-ed command. The hard thing is to define the sudo function so you don't lose this behavior.
I suggest something like the following. With the sudo
function, we read the first argument. If it's v
we do sudo -E nvim
. If it's another alias, we expand to the value of that alias. If it's not an alias at all, we just use the regular sudo command:
# for regular use, keep this alias
alias v='nvim'
# replace sudo with this functiom
sudo() {
# check if next argument is 'v'
if [[ "$1" == "v" ]] ; then
# remove 'v' from the argument list
shift
# call sudo -E nvim on remaining arguments
command sudo -E nvim "$@"
# exit the function with the return value of the
# sudo nvim -E command
return $?
fi
# now check if first argument is a different alias; if so,
# $expansion will be the alias definition if one exists,
# or else it will be the empty string
local expansion="${BASH_ALIASES[$1]}"
if [[ -n "$expansion" ]] ; then
# remove the alias from the argument list
shift
#if the expansion has variables in it,
#we need to expand those variables, not
#just the $expansion variable itself,
#so we use eval
eval "command sudo $expansion \"\$@\""
# exit the function with its return value
return $?
fi
# if we got here, what follows sudo is a
# normal command, so we execute sudo with the
# rest of the arguments as is
command sudo "$@"
}
There might be a simpler way, but I think this should work.
There are of course other simpler alternatives like having aliases with sudo in them, using sudoedit, etc. (some of which are described in the other answers), but with slightly different syntax than what you requested.
sudoedit
?