简体   繁体   中英

Ask user to run makefile from root mode

I have a makefile and configure shell in my project. I wrote code to ask user to run configure shell in root mode using the following code.

[ "$(whoami)" != "root" ] && exec sudo -- "$0" "$@"

But when I run ' make install ' I need to ask user to run from root mode. So I just copied the code from the configure shell and copied it in another shell script file called ' runasroot.sh '. Then I run this shell script from the make install .

install:
    @echo About to install XXX Project
    ./runasroot.sh
    find . -name "*.cgi" -exec cp {}  $(SCRIPTDEST)/ \;

When I run the above code, I got the below error.

About to install XXX Project
./runasroot.sh \;
make: *** [install] Error 1

runasroot.sh

#!/bin/bash
[ "$(whoami)" != "root" ] && exec sudo -- "$0" "$@"
target:
       @if ! [ "$(shell id -u)" = 0 ];then
             @echo "You are not root, run this target as root please"
             exit 1
       fi

There are several mistakes done here.

The first problem is what you're trying to do. It is very bad form to require root as part of the build process. For the build part, try to not require root for compiling anything. If you need to create special files as part of the packaging, use fakeroot or fakeroot-ng to get the same effect without any actual privilege escalation.

For install, just let the user run your entire make file as root, if she so chooses. Many operations that usually require root sometimes don't. For example, make install does not require root if the install is to a DESTDIR where the user has privileges.

If you are dead set on doing this anyway, however, your flow is completely wrong. While runasroot.sh does exactly what you want it to do, it only does so for itself. When you look at your make receipt:

install:
    @echo About to install XXX Project
    ./runasroot.sh # <<-- this line runs as root
    find . -name "*.cgi" -exec cp {}  $(SCRIPTDEST)/ \;

The runasroot.sh line runs as root, but the find line is a different process, and is completely unaffected.

That would be true for regular shell script, but it's doubly true for a make receipt. In a shell script, each command gets its own process. In a make receipt, each command gets its own shell . Your runasroot.sh does not, and cannot, affect the privileges under which the find runs.

So, what you are trying to do is both impossible and unwanted. Just try to install and fail if you don't have enough permissions.

Explanations

You can use ifneq to check that the user is not root and echo a message for instance, not performing the actual action is the user was indeed a root user. Since the id of the root user is usually 0 on a UNIX-like operating system, we can check that the user ID is 0 (or not) in a conditional.

Proposal solution

install:
ifneq ($(shell id -u), 0)
    @echo "You must be root to perform this action."
else
    @echo "TODO: The action when the user is root here..."
endif

Output

$ make install
You must be root to perform this action.
$ sudo make install
TODO: The action when the user is root here...

External resources

Conditional Parts of Makefiles

The shell Function

Recipe Echoing

Man for the id function

What is a root user

Call make again with sudo if user is not root:

install:
ifneq ($(shell id -u), 0)
    sudo make $@
else
    echo Installing...
endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM