4

This question is not duplicate of Ignore sudo in bash script


I am making a docker image based on Ubuntu 14.04 docker image. As you know, root is default user in docker. When I ran a bash script to install a software, got

sudo: error in /etc/sudo.conf, line 0 while loading plugin `sudoers_policy'
sudo: /usr/lib/sudo/sudoers.so must be owned by uid 0
sudo: fatal error, unable to load plugins

I have tried chown root /usr/lib/sudo/sudoers.so,but it is not working.


This behavior is weird :

ls    (everyone can do this)
sudo ls   (you can't do this even if you are root)

Because I am building a docker image, I don't want to install uncorrelated packages to make sudo support root. But there are bunch of sudo in some bash scripts,so simply replacing sudo to empty may not a good choice.

So I'm wondering if is there any way to only ignore sudo when you are root

Camden
  • 617
Mithril
  • 2,381
  • 3
  • 22
  • 30
  • Well, if root is the only user, you are running the script as root and there is no need for sudo in your script. In general, IMO, sudo in scripts is sloppy as, rather then calling sudo within your script, simply remove sudo and run the script as root via sudo script.sh So ltl;dr simply remove sudo from your script, you can do this with sed. – Panther Jul 19 '17 at 03:56

2 Answers2

7

In your scripts, towards the beginning, define sudo to be a function that calls the actual sudo if needed:

sudo ()
{
    [[ $EUID = 0 ]] || set -- command sudo "$@"
    "$@"
}

command sudo foo bar tells bash to use the actual sudo command instead of functions or aliases. $EUID is the effective user ID, which might be different from $UID.

muru
  • 197,895
  • 55
  • 485
  • 740
  • What exactly is the use of set --? I'm unable to understand the explanations given in set --help or man set. – Love XFCE May 26 '21 at 13:19
  • 1
    @LoveXFCE it sets the arguments for the function in which it is run (or script/shell/subshell, if run outside a function). Say you run sudo foo bar. In the function, the arguments are foo and bar. If you're not root, set replaces these with command, sudo, foo, bar. Then the function runs the arguments as a command. – muru Jun 10 '21 at 07:41
1

Disclaimer: Does not work with pipes

An alternative to the answer by @muru is to use an alias and a check if the user is root. This avoids running the commands in function and the side effects that that might have. A solution that should work on all shells (tested on Alpine Linux):

if [ $(id -u) -eq 0 ]; then
  alias sudo=eval
fi

On more modern shells, the following can also be used:

if (( $EUID == 0 )); then
  alias sudo=eval
fi
Moritz
  • 142
  • 8