0

There are two things I want: 1) I want that if I keep using sudo often that it never asks me for my password by updating my cached credentials every time I type sudo, 2) That I can use (certain) aliases while using sudo.

In order to update ones credentials one has to execute sudo -v (without command).

For example, I do not have a /usr/bin/vi. I do have a /usr/bin/nvim. I have an alias:

alias vi='/usr/bin/nvim'

So, if I type as non-root:

sudo vi /etc/fstab

Then I want that is executed:

sudo -v
sudo /usr/bin/nvim /etc/fstab

I tried to achieve this by creating the bash function:

function sudo()
{
  command sudo -v
  command sudo "$@"
}

However, this results in the error:

sudo: vi: command not found

In other words, the alias vi is not expanded from the "$@" inside the sudo function.

How can I fix this?

2 Answers2

1

Perhaps

function sudo()
{
  command sudo -v
  if [[ $(type -t "$1") == "alias" ]]; then
    set -- bash -ic "$(alias "$1"); $(printf "%q " "$@")"
  fi
  # what am I about to execute
  printf "%q " sudo "$@"; echo
  # and do it
  command sudo "$@"
}
glenn jackman
  • 85,964
  • Did you test it? I get errors: bash: -c: line 0: unexpected EOF while looking for matching ``', bash: -c: line 1: syntax error: unexpected end of file. – Carlo Wood May 05 '20 at 16:50
  • OK, this should fix it. The root shell needs to be interactive. – glenn jackman May 05 '20 at 19:54
  • Awesome, this works! So, the trick here is that you expand the alias(es) in an "interactive" shell by printing "$@" to printf using %q. I don't think I saw that trick anywhere yet! Clever! – Carlo Wood May 05 '20 at 21:01
  • The $(alias "$1") part adds your alias to the root shell (there was an error here in the last iteration). Then the $(printf ...) part adds (into the root shell script) the function arguments to be executed. I use %q because otherwise we quickly get into quoting hell. – glenn jackman May 05 '20 at 21:07
0

Although Kamil's alias sudo='sudo -v; sudo ' works equally well as glenn's answer, namely expanding the first word after sudo if that is an alias; it could be seen as a security issue to "blindly" expand aliases.

In the light of a possible configuration for visudo of

/etc/sudoers:

Defaults editor=/usr/bin/nvim, !env_editor

which ignores the EDITOR environment variable (equally a security risk) and always opens /etc/sudoers with /usr/bin/nvim one could use the following bash function as well (assume you're in the habbit of typing vi as your editor):

~/.bashrc:

sudo ()
{ 
    command sudo -nv 2> /dev/null;
    COMMAND="$1";
    shift;
    [ "$COMMAND" = "vi" ] && COMMAND="/usr/bin/nvim";
    command sudo "$COMMAND" "$@"
}

which likewise will then allow

sudo vi /etc/fstab

but always use /usr/bin/nvim, without expanding an alias.

Also note the use of sudo -nv as opposed to sudo -v. This is to avoid the latter asking for a password when the real command doesn't require one.