脚本如何检查它是否以root身份运行?


104

我正在编写一个简单的bash脚本,但是我需要它来检查它是否以root身份运行。我知道可能有一个非常简单的方法来做到这一点,但我不知道如何做。

只需说明一下:
编写脚本foo.sh以便命令./foo.sh输出0和命令sudo ./foo.sh输出的简单方法是什么1

Answers:


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

7
我接受了这一原因(经过一些测试),使用系统变量EUID的结果比运行命令(id -u)的速度(大约100倍)快,但是所有答案都非常有效。
马拉巴巴

18
此外,$UID$EUID是bash化。仅符合POSIX的外壳没有这些变量,您需要使用这些变量id(1)
David Foerster,2014年

3
在bash脚本中,您可以使用if ((EUID)); then,请参阅@geirha的评论
jfs

7
@Andrew:将变量传递给之前先对其进行替换sudo。如果您运行sudo sh -c 'echo $EUID',将会看到预期的结果。
M. Dudley

6
@Andrew –我知道我来晚了,但为了后代:这$EUID是一种Bashism(正如@DavidFoerster上文所述),您/bin/sh很可能是/bin/dash,而不是的链接/bin/bashsudo bash -c 'echo $EUID'将产生预期的结果。
阿德里安·

118

root用户不必被命名为“ root”。whoami返回具有用户ID的第一个用户名0$USER包含已登录用户的名称,可以具有用户ID 0,但名称不同。

唯一可靠的程序,用于检查帐户是否以root用户身份登录:

id -u

我使用-u有效用户ID,而不是-r真正的用户ID。权限判断有效用户ID,而不是真正的一个。

测验

/etc/passwd包含以下具有用户ID的用户名0(按给定顺序):

rootx
root2

以身份登录root2,可得到以下结果:

  • whoamirootx
  • echo $USER:(root2如果程序是在空环境中启动的,则返回一个空字符串,例如env -i sh -c 'echo $USER'
  • id -u0 如您所见,其他程序在此检查中失败,仅id -u通过了。

更新后的脚本如下所示:

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


5
我总是尽量使用shdash)而不是来保持与POSIX的兼容性bash。但是射门好,节省了另一把叉子:)
Lekensteyn 2011年

凉了一会儿后,我回来看看。Lekensteyn的方法确实确实更好。他的答案现在是新的接受答案。+ 1,Lekensteyn,尤其是。因为这个问题使他难以获得徽章;)
托马斯·沃德

感谢您等待了这么长时间接受我的问题:DI获得了金民粹徽章和青铜色尼斯答案。
Lekensteyn 2011年

3
我看到了较短的版本[ -w / ]。这个想法保持不变。注意:在某些chroot中,[ -w /etc/shadow ]将由于/etc/shadow不存在而失败,因此/首选使用。一种更好的方法是检查对root权限的实际需求。如果脚本需要写入/etc/someconfig,只需检查该文件是否可写或该文件不存在且/etc可写。
Lekensteyn 2011年

30

正如@Lekensteyn所说,您应该使用有效的用户ID。您不需要调用id -ubash:

#!/bin/bash

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

@geirha在评论中的建议使用算术评估:

#!/bin/bash

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

7
通常,应该使用它((..))来测试数字,以及[[..]]测试字符串和文件,所以我会if (( EUID != 0 )); then改用或者仅仅是if ((EUID)); then
geirha 2011年

@geirha:我添加了您的建议。
jfs

2
EUID应该成为$EUID。代替使用(( $EUID != 0 )),使用[ $EUID != 0 ]。它也可以使用dash
Lekensteyn 2011年

2
@Lekensteyn:EUID很好。该问题被标记为bashnot dash。该命令env -i sh -c '[ $EUID != 0 ]'失败,但是env -i bash -c '(( EUID != 0 ))'有效。顺便说一句,dash不适用于Ubuntu stackoverflow.com/questions/5160125/上的某些非ascii字符。现在是2011年,有人使用其他语言。
jfs

在经过无聊的无聊回顾和测试之后,我将使用此处列出的方法,并从现在开始使用它$EUID。结果,我更改了接受的答案。
托马斯·沃德

20

您可以使用以下whoami命令来完成此操作,该命令返回当前用户:

#!/bin/bash

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

...

You must be root to do this.如果当前用户不是,则运行上述命令将打印root


注意:在某些情况下,一种替代方法是简单地检查$USER变量:

if [ $USER != 'root' ]

我看一下代码,看看它是否不会使脚本失败或什么。如果有效,我会接受您的回答:)
托马斯·沃德

4
@乔治·爱迪生(George Edison):我建议不要使用$USER,尤其是这种方式。$USER是由登录shell设置的,因此不必传播到程序(env -i sh -c 'echo $USER')。这样,它$USER为空,并且发生语法错误。
Lekensteyn 2011年

1
@Lekensteyn不仅$USER由外壳设置,而且它很容易被欺骗。Whoami将返回实际用户。
Paul de Vrieze 2011年

2
@PauldeVrieze弄弄那张支票有什么意义?
htorque 2011年

1
@andrewsomething:$USER由您的shell解释,您的示例应该sudo sh -c 'echo $USER'是有意义的。@George:它使错误的假设whoami总是返回root的UID 0
萨姆·霍瑟瓦尔

11

考虑到效率,您可以首先测试EUID环境变量,然后如果不存在,请调用标准id命令:

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

这样,由于使用OR快捷方式,您避免调用系统命令,从而优先查询内存中的变量。

代码重用:

function amIRoot() {
  ! ((${EUID:-0} || "$(id -u)"))
}

恐怕您还没有对它进行基准测试,好吧,这与花费了相同的时间id -u。请在此处查看基准脚本及其下面的结果:pastebin.com/srC3LWQy
LinuxSecurityFreak


2

使脚本只能由root用户运行的一种简单方法是使用以下行启动脚本:
#!/bin/su root


1
不要这样 它尝试直接以root用户身份登录,而在许多系统上可能需要sudo,因为前者被禁止。此外,shebang旨在确保您的脚本在为其设计的脚本中运行,而您的方法将使脚本在root的默认shell中运行,如果脚本由作者以外的任何人运行,则无法预测。因此,使用shebang提升脚本特权将严重破坏其可移植性,并在许多系统上导致错误。(su:身份验证失败)
StarCrashr


1

该代码段将:

  • 检查不同的会话
  • 建议使用 sudo !!
  • 并返回错误
如果[[$(whoami&2> / dev / null)“!=” root“] && [” $(id -un&2> / dev / null)“!=” root“]
      然后
      echo“您必须是root用户才能运行此脚本!”
      回声“使用'sudo !!'”
      1号出口
科幻

1

这个答案只是为了保存一个想法,可能对您中的某些人有所帮助。如果您需要从桌面GUI运行并且需要root特权的脚本,请尝试以下方式:

#!/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

这样,您将获得一个漂亮的对话框窗口,询问您root用户密码。就像使用命令行sudo一样。

gksudo可能不会在你的系统中可用然后安装它sudo apt-get install gksu


0

此代码在未定义EUID的Bash和stock Bourne sh(在FreeBSD下测试)下均适用。如果存在EUID,则返回其值,否则运行'id'命令。它比上面的“或”示例短一点,因为它使用了内置的外壳“:-”。

根在sh:

# echo $EUID

# euid=${EUID:-`id -u`}
# echo $euid
0

In bash:
[chaapala@tenfwd2 ese]$ euid=${EUID:-`id -u`}
[chaapala@tenfwd2 ese]$ echo $euid
10260
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.