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

请明确:命令./foo.sh输出0,命令sudo ./foo.sh输出1

#1 楼

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


评论


我接受这一原因(经过一些测试),发现使用系统变量EUID比运行命令(id -u)快(大约100倍),但是所有答案都非常有效。

–马拉巴尔巴
2010年12月2日,11:59

同样,$ UID和$ EUID是bashisms。仅符合POSIX的外壳没有这些变量,您需要使用id(1)代替。

–大卫·福斯特(David Foerster)
14-10-16在9:28

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

– jfs
14-10-17在19:38

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

– M. Dudley
15年11月19日在18:09



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

– AdrianGünter
17年5月9日在21:40



#2 楼

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

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

id -u


我将-u用作有效用户ID,而不将-r用作真实用户ID。权限是由有效的用户ID而不是真实的用户ID决定的。 br />
rootx
root2


/etc/passwd登录,得到下一个结果: br /> 0root2(如果该程序是在空环境中启动的,则返回一个空字符串,例如whoami)。此检查仅通过rootx

更新后的脚本如下所示:

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


评论


我总是尽量保持与POSIX兼容,使用sh(破折号)作为解释器而不是bash。但是好球,节省了另一个分叉:)

– Lekensteyn
2011年3月13日在10:34

凉了一会儿后,我回来看看。 Lekensteyn的方法确实确实更好。现在,他的答案是新接受的答案。 + 1,Lekensteyn,尤其是为了摆脱这个问题而很难获得的徽章;)

–托马斯·沃德♦
2011年3月13日在18:13

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

– Lekensteyn
2011年3月13日在21:10

我仍然喜欢使用此测试:[-w / etc / shadow]。如果是这样,那么您也应该是root。 ;)

–Kees Cook
2011-3-14在22:44

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

– Lekensteyn
2011-03-14 22:47



#3 楼

正如@Lekensteyn所说,您应该使用有效的用户ID。您无需在bash中调用id -u

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


评论


通常,应该使用((..))来测试数字,并使用[[..]]来测试字符串和文件,因此,如果((EUID!= 0));然后取而代之,或者只是((EUID));然后

– Geirha
2011年3月13日在12:41

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

– jfs
2011年3月13日在13:11

EUID应该变成$ EUID。而不是使用[[($ EUID!= 0)),而是使用[$ EUID!= 0]。它也会与破折号一起工作。

– Lekensteyn
2011年3月13日在13:23

@Lekensteyn:EUID可以正常工作。这个问题被标记为bash而不是破折号。命令env -i sh -c'[$ EUID!= 0]'失败,但是env -i bash -c'((EUID!= 0))'有效。顺便说一句,破折号不适用于Ubuntu stackoverflow.com/questions/5160125/上的某些非ascii字符。现在是2011年,有人使用其他语言。

– jfs
2011年3月13日13:39



在经过令人无聊的无聊和测试后回顾了这一点之后,从现在开始,我将使用这里列出的方法与$ EUID一起使用。结果,我更改了接受的答案。

–托马斯·沃德♦
2011年8月3日15:15

#4 楼

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

注意:在某些情况下,另一种方法是简单地检查You must be root to do this.变量:

#!/bin/bash

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

...


评论


我将看一下代码,看看它是否不会使脚本失败或其他原因。如果有效,我会接受您的回答:)

–托马斯·沃德♦
2011-3-13在7:40



@乔治·爱迪生:我建议不要使用$ USER,尤其是这样。 $ USER由登录外壳程序设置,它不必传播到程序(env -i sh -c'echo $ USER')。这样,$ USER为空,并且发生语法错误。

– Lekensteyn
2011年3月13日在9:26

@Lekensteyn $ USER不仅由shell设置,它还很容易被欺骗。 Whoami将返回实际用户。

–Paul de Vrieze
2011年3月13日在11:48

@PauldeVrieze欺骗该支票有什么意义?

–扭矩
2011年3月13日下午14:01

@andrewsomething:$ USER由您的shell解释,您的示例应为sudo sh -c'echo $ USER',以使其有意义。 @George:做出错误的假设,即whoami将始终为UID 0返回root。

–sam hocevar
2011年3月13日在20:26

#5 楼

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

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


这种方式,因为有了OR快捷方式,您避免了调用系统命令,而是优先考虑内存中变量的查询。

代码重用:

评论


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

– LinuxSecurityFreak
19-10-16在23:40

((($ {EUID:-0} ||“ $(id -u)”)))始终运行id -u,就像(((1 || $(echo hi>&2; echo 1))))和(((0 || $(echo hi>&2; echo 1)))都显示hi。外壳程序算术&&和||是控制操作员;在||中“ $(b)”,b仅在“ $(b)”运行时运行。大多数扩展,包括命令替换,都由控制操作员的短路语义控制。 Shell算术也有碰巧被拼写为&&和||的运算符-这也短路,因为(((1 || 0/0))不是错误-但Shell算术在嵌套命令替换扩展后发生。

– Eliah Kagan
19-10-24在18:02



#6 楼

#!/bin/bash
[[ $(id -u) != 0 ]] 
echo $?


#7 楼

#!/bin/bash
uid=`id -u`
if [ "$uid" == "0" ]
then
    echo 1
else
    echo 0
fi


#8 楼

该代码段将:


检查不同的会话
建议使用sudo !!

并返回错误

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


#9 楼

此答案仅是为了节省点子,对您中的某些人可能会有帮助。
如果您需要从桌面GUI运行且需要root特权的脚本,请尝试以下方法: />
这样,您将获得一个漂亮的对话框,询问您root用户密码。就像使用命令行sudo一样。

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

#10 楼

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

评论


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

– StarCrashr
18-09-20在1:59



不要这样某些玩笑者可能会创建另一个名为root的用户,或者使一个名为root的用户不是root,从而使您的程序误以为是root。参见askubuntu.com/a/836621/1070384。

– Sapphire_Brick
20年8月18日在22:21

#11 楼

此代码在未定义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