如何检查是否在 bash 脚本中以 root 身份运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18215973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if running as root in a bash script
提问by Nathan
I'm writing a script that requires root level permissions, and I want to make it so that if the script is not run as root, it simply echoes "Please run as root." and exits.
我正在编写一个需要 root 级别权限的脚本,我想让它在脚本不是以 root 身份运行的情况下,它只是回应“请以 root 身份运行”。并退出。
Here's some pseudocode for what I'm looking for:
这是我正在寻找的一些伪代码:
if (whoami != root)
then echo "Please run as root"
else (do stuff)
fi
exit
How could I best (cleanly and securely) accomplish this? Thanks!
我怎样才能最好地(干净且安全地)完成这项工作?谢谢!
Ah, just to clarify: the (do stuff) part would involve running commands that in-and-of themselves require root. So running it as a normal user would just come up with an error. This is just meant to cleanly run a script that requires root commands, without using sudo inside the script, I'm just looking for some syntactic sugar.
啊,只是澄清一下:(做东西)部分将涉及运行本身需要 root 的命令。因此,以普通用户身份运行它只会出现错误。这只是为了干净地运行需要 root 命令的脚本,而不在脚本中使用 sudo,我只是在寻找一些语法糖。
采纳答案by Nathan
A few answers have been given, but it appears that the best method is to use is:
已经给出了一些答案,但似乎最好的方法是使用:
id -u
- If run as root, will return an id of 0.
id -u
- 如果以 root 身份运行,将返回 0 的 id。
This appears to be more reliable than the other methods, and it seems that it return an id of 0 even if the script is run through sudo
.
这似乎比其他方法更可靠,并且即使脚本运行通过它似乎也返回 0 id sudo
。
回答by ptierno
The $EUID environment variable holds the current user's UID. Root's UID is 0. Use something like this in your script:
$EUID 环境变量保存当前用户的 UID。Root 的 UID 是 0。在你的脚本中使用这样的东西:
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
Note:If you get 2: [: Illegal number:
check if you have #!/bin/sh
at the top and change it to #!/bin/bash
.
注意:如果你得到2: [: Illegal number:
检查你是否#!/bin/sh
在顶部并将其更改为#!/bin/bash
.
回答by sberder
In a bash script, you have several ways to check if the running user is root.
在 bash 脚本中,您有多种方法可以检查运行用户是否为 root。
As a warning, do not check if a user is root by using the root
username. Nothing guarantees that the user with ID 0 is called root
. It's a very strong convention that is broadly followed but anybody could rename the superuser another name.
作为警告,不要使用root
用户名检查用户是否为 root 。没有什么可以保证 ID 为 0 的用户被调用root
。这是一个非常强大的约定,被广泛遵循,但任何人都可以将超级用户重命名为另一个名称。
I think the best way when using bashis to use $EUID
, from the man page:
我认为使用bash的最佳方法是使用$EUID
手册页中的 , :
EUID Expands to the effective user ID of the current user, initialized
at shell startup. This variable is readonly.
This is a better way than $UID
which could be changed and not reflect the real user running the script.
这是一种比$UID
可以更改且不反映运行脚本的真实用户更好的方法。
if (( $EUID != 0 )); then
echo "Please run as root"
exit
fi
A way I approach that kind of problem is by injecting sudo
in my commands when not run as root. Here is an example:
我解决这种问题的一种方法是sudo
在不以 root 身份运行时注入我的命令。下面是一个例子:
SUDO=''
if (( $EUID != 0 )); then
SUDO='sudo'
fi
$SUDO a_command
This ways my command is run by root when using the superuser or by sudo
when run by a regular user.
这样我的命令在使用超级用户时或由sudo
普通用户运行时由 root运行。
If your script is always to be run by root, simply set the rights accordingly (0500
).
如果您的脚本总是由 root 运行,只需相应地设置权限 ( 0500
)。
回答by Dale_Reagan
if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi
or
或者
if [[ `id -u` -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi
:)
:)
回答by Jeremy J Starcher
As @wrikken mentioned in his comments, id -u
is a much better check for root.
正如@wrikken 在他的评论中提到的,id -u
对 root 的检查要好得多。
In addition, with proper use of sudo
, you could have the script check and see if it is running as root. If not, have it recall itself via sudo
and then run with root permissions.
此外,通过正确使用sudo
,您可以检查脚本并查看它是否以 root 身份运行。如果没有,让它通过调用它自己sudo
,然后以 root 权限运行。
Depending on what the script does, another option may be to set up a sudo
entry for whatever specialized commands the script may need.
根据脚本的作用,另一个选项可能是为sudo
脚本可能需要的任何专门命令设置一个条目。
回答by Slater Victoroff
There is a simple check for a user being root.
有一个简单的检查用户是 root 用户。
The [[ stuff ]]
syntax is the standard way of running a check in bash.
该[[ stuff ]]
语法是运行在bash检查的标准方式。
error() {
printf '\E[31m'; echo "$@"; printf '\E[0m'
}
if [[ $EUID -eq 0 ]]; then
error "Do not run this as the root user"
exit 1
fi
This also assumes that you want to exit with a 1 if you fail. The error
function is some flair that sets output text to red (not needed, but pretty classy if you ask me).
这也假设您想在失败时以 1 退出。该error
功能是一些将输出文本设置为红色的天赋(不需要,但如果你问我的话非常优雅)。
回答by Matthew Trotter
Very simple way just put:
很简单的方法就放:
if [ "$(whoami)" == "root" ] ; then
# you are root
else
# you are not root
fi
The benefit of using this instead of id
is that you can check whether a certain non-root user is running the command, too; eg.
使用它代替的好处id
是您可以检查某个非 root 用户是否也在运行该命令;例如。
if [ "$(whoami)" == "john" ] ; then
# you are john
else
# you are not john
fi
回答by Sergio Abreu
0- Read official GNU Linux documentation, there are many ways to do it correctly.
0- 阅读官方 GNU Linux 文档,有很多方法可以正确地做到这一点。
1- make sure you put the shell signature to avoid errors in interpretation:
1- 确保您输入了 shell 签名以避免解释错误:
#!/bin/bash
2- this is my script
2-这是我的脚本
#!/bin/bash
if [[ $EUID > 0 ]]; then # we can compare directly with this syntax.
echo "Please run as root/sudo"
exit 1
else
#do your stuff
fi
回答by LinuxSecurityFreak
In this answer, let it be clear, I presume the reader is able to read bash
and POSIXshell scripts like dash
.
在这个答案,让它很清楚,我相信读者能够阅读bash
和POSIX像Shell脚本dash
。
I believe there is not much to explain here since the highly voted answers do a good job of explaining much of it.
我相信这里没有什么可解释的,因为高票数的答案很好地解释了其中的大部分内容。
Yet, if there is anything to explain further, don't hesitate to comment, I will do my best filling the gaps.
但是,如果有什么要进一步解释的,请不要犹豫,发表评论,我会尽力填补空白。
Optimized all-round (not only bash
) solution for performance and reliability; all shells compatible
bash
优化bash
性能和可靠性的全方位(不仅)解决方案;所有外壳兼容
bash
New solution:
新解决方案:
# bool function to test if the user is root or not
is_user_root () { [ ${EUID:-$(id -u)} -eq 0 ]; }
Benchmark (save to file is_user_root__benchmark
)
基准(保存到文件is_user_root__benchmark
)
###############################################################################
## is_user_root() benchmark ##
## Bash is fast while Dash is slow in this ##
## Tested with Dash version 0.5.8 and Bash version 4.4.18 ##
## Copyright: 2020 Vlastimil Burian ##
## E-mail: [email protected] ##
## License: GPL-3.0 ##
## Revision: 1.0 ##
###############################################################################
# intentionally, the file does not have executable bit, nor it has no shebang
# to use it, please call the file directly with your shell interpreter like:
# bash is_user_root__benchmark
# dash is_user_root__benchmark
# bool function to test if the user is root or not
is_user_root () { [ ${EUID:-$(id -u)} -eq 0 ]; }
# helper functions
print_time () { date +"%T.%2N"; }
print_start () { printf '%s' 'Start : '; print_time; }
print_finish () { printf '%s' 'Finish : '; print_time; }
readonly iterations=10000
printf '%s\n' '______BENCHMARK_____'
print_start
i=1; while [ $i -lt $iterations ]; do
is_user_root
i=$((i + 1))
done
print_finish
Original solution:
原解决方案:
#!/bin/bash
is_user_root()
# function verified to work on Bash version 4.4.18
# both as root and with sudo; and as a normal user
{
! (( ${EUID:-0} || $(id -u) ))
}
if is_user_root; then
echo 'You are the almighty root!'
else
echo 'You are just an ordinary user.'
fi
#!/bin/bash
is_user_root()
# function verified to work on Bash version 4.4.18
# both as root and with sudo; and as a normal user
{
! (( ${EUID:-0} || $(id -u) ))
}
if is_user_root; then
echo 'You are the almighty root!'
else
echo 'You are just an ordinary user.'
fi
^^^ The striked-out solution was proven not to speed things up, but it has been around for a long time, so I'm going to keep it here as long as I see necessary.
^^^ 经证明不会加快速度,但它已经存在很长时间了,所以只要我认为有必要,我就会把它保留在这里。
Explanation
解释
Since it is multitude times faster to read the $EUID
standard bash
variable, the effective user ID number, than executing id -u
command to POSIX-ly find the user ID, this solution combines both into a nicely packed function. If, and only if, the $EUID
is for any reason not available, the id -u
command will get executed, ensuring we get the proper return value no matter the circumstances.
由于读取$EUID
标准bash
变量(有效用户 ID 号)比执行id -u
命令以POSIX-ly 查找用户 ID快许多倍,因此该解决方案将两者结合成一个很好的打包函数。当且仅当$EUID
由于任何原因不可用时,该id -u
命令才会被执行,确保我们在任何情况下都能获得正确的返回值。
Why I post this solution after so many years the OP has asked
为什么我在 OP 询问了这么多年后发布此解决方案
Well, if I see correctly, there does seem to be a missing piece of code above.
好吧,如果我没看错,上面似乎确实缺少一段代码。
You see, there are many variableswhich have to be taken into account, and one of them is combining performance and reliability.
你看,有许多变量需要考虑,其中之一是结合性能和可靠性。
Portable POSIXsolution + Example of usage of the above function
便携式POSIX解决方案+上述函数的使用示例
#!/bin/sh
# bool function to test if the user is root or not (POSIX only)
is_user_root() { [ "$(id -u)" -eq 0 ]; }
if is_user_root; then
echo 'You are the almighty root!'
exit 0 # unnecessary, but here it serves the purpose to be explicit for the readers
else
echo 'You are just an ordinary user.' >&2
exit 1
fi
Conclusion
结论
As much as you possibly don't like it, the Unix / Linux environment has diversified a lot. Meaning there are people who like bash
so much, they don't even think of portability (POSIXshells). Others like me prefer the POSIXshells. It is nowadays a matter of personal choice and needs.
尽管您可能不喜欢它,但 Unix / Linux 环境已经多样化了很多。这意味着有些人非常喜欢bash
,他们甚至不考虑可移植性(POSIXshell)。像我这样的其他人更喜欢POSIXshell。如今,这是个人选择和需求的问题。
回答by John Kugelman
If the script really requires root access then its file permissions should reflect that. Having a root script executable by non-root users would be a red flag. I encourage you not to control access with an if
check.
如果脚本确实需要 root 访问权限,那么它的文件权限应该反映这一点。让非 root 用户执行 root 脚本将是一个危险信号。我鼓励您不要通过if
支票来控制访问。
chown root:root script.sh
chmod u=rwx,go=r script.sh