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?

6
  • Perhaps unix.stackexchange.com/q/148545/117549 ?
    – Jeff Schaller
    May 5, 2020 at 16:07
  • Ditto. This answer adjusted to your requirements: alias sudo='sudo -v; sudo ' May 5, 2020 at 16:08
  • @KamilMaciorowski Not working. sudo: vi: command not found
    – Carlo Wood
    May 5, 2020 at 16:16
  • I tried a billion things and absolutely nothing works :/.
    – Carlo Wood
    May 5, 2020 at 16:34
  • The alias I gave you works for me in Bash 4.4.12. Did you type it? or did you paste? Maybe you missed the space just before the closing quote. It's crucial. May 5, 2020 at 17:28

2 Answers 2

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 "$@"
}
4
  • 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 5, 2020 at 16:50
  • OK, this should fix it. The root shell needs to be interactive. May 5, 2020 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 5, 2020 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. May 5, 2020 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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .