Linux check if you are root

How can a script check if it’s being run as root?

I’m writing a simple bash script, but I need it to check whether it’s being run as root or not. I know there’s probably a very simple way to do that, but I have no idea how. Just to be clear:
What’s a simple way to write a script foo.sh, so that the command ./foo.sh outputs 0 , and the command sudo ./foo.sh outputs 1 ?

11 Answers 11

#!/bin/bash if [[ $EUID -ne 0 ]]; then echo "This script must be run as root" exit 1 fi 

I’m accepting this one cause (after some testing) using the system variable EUID turned out to be (approx 100 times) faster than running a command (id -u), but all of the answers worked great.

Also, $UID and $EUID are bashisms. Merely POSIX compliant shells don’t have those variables and you need to use id(1) instead.

@Andrew: Variables are substituted before they are passed to sudo . If you run sudo sh -c ‘echo $EUID’ you will see your expected results.

@Andrew – I know I’m way late here, but for posterity: $EUID is a Bashism (as mentioned above by @DavidFoerster), and your /bin/sh is most likely a link to /bin/dash , not /bin/bash . sudo bash -c ‘echo $EUID’ will yield the expected result.

A root user does not have to be named «root». whoami returns the first username with user ID 0 . $USER contains the name of the logged in user, which can have user ID 0 , but have a different name.

The only reliable program to check whether the account is logged in as root, or not:

I use -u for the effective user ID, not -r for the real user ID. Permissions are determined by the effective user ID, not the real one.

Tests

/etc/passwd contains the following usernames with user ID 0 in the given order:

Logged in as root2 , gives the next results:

  • whoami : rootx
  • echo $USER : root2 (this returns an empty string if the program was started in an empty environment, e.g. env -i sh -c ‘echo $USER’ )
  • id -u : 0 As you can see, the other programs failed in this check, only id -u passed.

The updated script would looks like this:

#!/bin/bash if ! [ $(id -u) = 0 ]; then echo "I am not root!" exit 1 fi 

I always try to stay as POSIX compliant as possible, using sh ( dash ) as interpreter instead of bash . But good shot, saves another fork 🙂

After being out cold for a while, i came back and took a look. Lekensteyn’s method does indeed seem to be better. His answer is now the new accepted answer. +1 to you, Lekensteyn, esp. for getting that hard-to-get badge off of this question 😉

Thanks for waiting that long for accepting my question 😀 I got a Gold Populist badge and a bronze Nice Answer for this answer 🙂 I wonder how this question got that popular, 345 views in a day!

Читайте также:  Linux source code repository

I’ve seen shorter versions, [ -w / ] . The idea remains the same. Note: in certain chroots, [ -w /etc/shadow ] will fail because /etc/shadow is non-existent, therefore the approach with / is preferred. A way better would checking the actual need for root permissions. If the script needs to write to /etc/someconfig , just check if that file is writable OR the file does not exist and /etc is writable.

As @Lekensteyn said you should use effective user ID. You don’t need to call id -u in bash:

#!/bin/bash if [[ $EUID -ne 0 ]]; then echo "You must be root to do this." 1>&2 exit 100 fi 

@geirha’s suggestion from the comments uses arithmetic evaluation:

#!/bin/bash if (( EUID != 0 )); then echo "You must be root to do this." 1>&2 exit 100 fi 

In general one should use ((..)) for testing numbers, and [[..]] for testing strings and files, so I’d do if (( EUID != 0 )); then instead, or just if ((EUID)); then

EUID should become $EUID . Instead of using (( $EUID != 0 )) , use [ $EUID != 0 ] . It will work with dash too.

@Lekensteyn: EUID works just fine. The question is tagged bash not dash . The command env -i sh -c ‘[ $EUID != 0 ]’ fails, but env -i bash -c ‘(( EUID != 0 ))’ works. btw, dash doesn’t work for some non-ascii characters on Ubuntu stackoverflow.com/questions/5160125/… It is 2011 and there are people who use other languages.

After looking back on this while being horribly bored, and testing, I am going to use this method as listed here with the $EUID stuff from this point forward. I have changed the accepted answer as a result.

You can accomplish this by using the whoami command, which returns the current user:

#!/bin/bash if [ `whoami` != 'root' ] then echo "You must be root to do this." exit fi . 

Running the above will print You must be root to do this. if the current user is not root .

Note: an alternative in some cases is to simply check the $USER variable:

@George Edison: I recommend against using $USER , especially in this way. $USER is set by the login shell, it does not necessary propagate to the program ( env -i sh -c ‘echo $USER’ ). In that way, $USER is empty and an syntax error occurs.

@Lekensteyn Not only is $USER set by the shell, it is also something that is easy to spoof. Whoami will return the actual user.

id -u is a far superior solution. I believe this answer is potentially misleading and should not have been accepted.

@andrewsomething: $USER is interpreted by your shell, your example should be sudo sh -c ‘echo $USER’ in order to be meaningful. @George: it makes the wrong assumption that whoami will always return root for UID 0.

Читайте также:  Распаковать архив части linux

Taking efficiency into consideration, you may test, first, the EUID environment variable and then, if it doesn’t exist, call the standard id command:

if (($ || "$(id -u)")); then echo You are not root. else echo Hello, root. fi 

This way, because of the OR shortcut, you avoid calling a system command, prioritizing the query of an in-memory variable.

I’m afraid you haven’t benchmarked it, well I have and this takes the very same time as id -u . See the bench script along with results below it here: pastebin.com/srC3LWQy

(($ || «$(id -u)»)) always runs id -u , just as ((1 || $(echo hi >&2; echo 1))) and ((0 || $(echo hi >&2; echo 1))) both print hi . Outside shell arithmetic, && and || are control operators; in a || «$(b)» , b only runs if «$(b)» runs. Most expansions, including command substitution, are governed by control operators’ short-circuiting semantics. Shell arithmetic has operators that happen to be spelled && and || , too—which also short-circuit in that ((1 || 0/0)) is not an error—but shell arithmetic occurs after nested command substitutions are expanded.

Numeric comparison is better done with -ne (counter-intuitive: text operands are for numeric comparison)

#!/bin/bash if [ "$(id -u)" == "0" ] then echo "I am root." else echo "I am not root." fi 
if [ "$(whoami &2>/dev/null)" != "root" ] && [ "$(id -un &2>/dev/null)" != "root" ] then echo "You must be root to run this script!" echo "use 'sudo !!'" exit 1 fi

This answer is just to save an idea with may be helpful for some of you. If you need script which is run from desktop GUI and requires root privileges try this way:

#!/bin/bash if ! [ $(id -u) = 0 ]; then gksudo -w $0 $@ exit fi #here go superuser commands, e.g. (switch intel cpu into powersave mode): echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo cpupower frequency-set -g powersave 

This way you will get nice dialog window asking you for root user password. Just like with command-line sudo.

The gksudo may not be available in your system then install it with sudo apt-get install gksu .

One simple way to make the script only runnable by root is to start the script with the line:
#!/bin/su root

Don’t do this. It attempts to log in directly as root, whereas sudo may be required on many systems because the former is forbidden. Furthermore, the shebang is intended to ensure your script runs in the one for which it was designed, whereas your method will cause the script to run in root’s default shell, which cannot be predicted if the script is run by anyone other than the author. Therefore, using the shebang to elevate privileges of a script will severely break its portability and result in errors on many systems. (su: Authentication failure)

Читайте также:  Linux redis как посмотреть

Don’t do this. Some joker might create a second user named root , or make a user named root that isn’t root , thereby fooling your program into thinking it’s root . See askubuntu.com/a/836621/1070384.

Источник

BASH: Check if user is root even when using fakeroot [duplicate]

but if the script was invoked via fakeroot, UID and EUID are both 0 (of course, as fakeroot fakes root privileges). But is there any way to check whether the user is root? Without trying to do something only root can do (i.e. creating a file in /)?

Why are you trying to tell the difference between fakeroot and real root? The purpose of fakeroot is to pretend to be root. Trying to distinguish them seems to be defeating that purpose.

@RyanThompson — you are right. Functionally, we shouldn’t distinguish between real root and fakeroot. However, there are cases when there’s a need to know who is runnng the fakeroot. Maybe for logging and auditing purposes. Of course it might not be the same case in OPs question.

That is correct. But when I have a script that can be read by any user and they could execute (or at least read) the script, I have to check whether the script is executed by the «real» root.

2 Answers 2

Fakeroot sets custom LD_LIBRARY_PATH that contains paths to libfakeroot . For example:

/usr/lib/x86_64-linux-gnu/libfakeroot:/usr/lib64/libfakeroot:/usr/lib32/libfakeroot 

You can use this to detect if application is running inside the fakeroot iterating by paths and looking for libfakeroot .

IS_FAKEROOT=false for path in $; do if [[ "$path" == *libfakeroot ]]; then IS_FAKEROOT=true break fi done echo "$IS_FAKEROOT" 

You can simplify this to [[ «$LD_LIBRARY_PATH:» = *libfakeroot:* ]] (note: the «:» on the end of «libfakeroot:» makes it only match the end of path entries, the one on «$LD_LIBRARY_PATH:» allows it to match the final entry as well). Bonus: this works safely with path entries that include spaces and/or wildcards.

Here, The below script will find the user is root or not.

#!/bin/bash touch /checkroot 2>/dev/null uid=`stat -c "%u" /checkroot 2>/dev/null` if [ "$uid" = "0" ] then echo "Root user" else echo "Not a root user" fi rm /checkroot 2>/dev/null 

In the above example, I will try to create a file in the root directory, if I am not a root user and I don’t have a permission it will give error, I was redirect that error to the /dev/null.

If the user have the permission, the file will be created. Then using the stat to get the user id for that file, and store that into the variable uid.

Using that variable in the if condition I will check.

If the temporary file will be created the rm command will remove that file.

But make sure the file is not already exist in the root directory.

Источник

Оцените статью
Adblock
detector