乐趣区

关于linux:深度解析Linux-命令-su-和-sudo-的区别

之前始终对 su 和 sudo 这两个命令犯迷糊,最近专门搜了这方面的材料,总算是把两者的关系以及用法搞清楚了,这篇文章来零碎总结一下。

筹备工作

因为本篇博客中波及到用户切换,所以我须要提前准备好几个测试用户,不便后续切换。

Linux 中新建用户的命令是 useradd,个别零碎中这个命令对应的门路都在 PATH 环境变量里,如果间接输出 useradd 不论用的话,就用绝对路径名的形式:/usr/sbin/useradd。

useradd 新建用户命令只有 root 用户能力执行,咱们先从普通用户 ubuntu 切换到 root 用户(如何切换后文会介绍):

ubuntu@VM-0-14-ubuntu:~$ su -
Password:                                    # 输出 root 用户登录明码
root@VM-0-14-ubuntu:~# useradd -m test_user     # 带上 -m 参数
root@VM-0-14-ubuntu:~# ls /home
test_user  ubuntu              # 能够看到 /home 目录上面有两个用户了

因为还没有给新建的用户 test_user 设置登录明码,这就导致咱们无奈从普通用户 ubuntu 切换到 test_user,所以接下来,咱们须要用 root 来设置 test_user 的登录明码。须要用到 passwd 命令:

root@VM-0-14-ubuntu:~# passwd test_user
Enter new UNIX password:           # 输入 test_user 的明码
Retype new UNIX password:       
passwd: password updated successfully
root@VM-0-14-ubuntu:~#

接着咱们输出 exit 退出 root 用户到 普通用户 ubuntu:

root@VM-0-14-ubuntu:~# exit
logout
ubuntu@VM-0-14-ubuntu:~$

能够看到,命令提示符后面曾经由 root 变成 ubuntu,阐明咱们当初的身份是 ubuntu 用户。

su 命令介绍及次要用法

首先须要解释下 su 代表什么意思。

之前始终认为 su是 super user,查阅材料之后才晓得原来示意switch user。晓得 su 是由什么缩写来的之后,那么它提供的性能就不言而喻了,就是切换用户。

参数

su 的个别应用办法是:

su  <user_name>
或者
su - <user_name>

两种办法只差了一个字符 -,会有比拟大的差别:

  • 如果退出了 – 参数,那么是一种 login-shell 的形式,意思是说切换到另一个用户 <user_name> 之后,以后的 shell 会加载 <user_name> 对应的环境变量和各种设置;
  • 如果没有退出 – 参数,那么是一种 non-login-shell 的形式,意思是说我当初切换到了 <user_name>,然而以后的 shell 还是加载切换之前的那个用户的环境变量以及各种设置。

光解释会比拟形象,咱们看一个例子就比拟容易了解了。

咱们首先从 ubuntu 用户以 non-login-shell 的形式切换到 root 用户,比拟两种用户状态下环境变量中 PWD 的值(su 命令不跟任何 <user_name>,默认切换到 root 用户):

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu                        # 是 /home/ubuntu
HOME=/home/ubuntu
# 省略......
ubuntu@VM-0-14-ubuntu:~$ su             # non-login-shell 形式
Password:                               # 输出 root 用户登录明码
root@VM-0-14-ubuntu:/home/ubuntu# env | grep ubuntu
PWD=/home/ubuntu                        # 能够发现还是 /home/ubuntu
root@VM-0-14-ubuntu:/home/ubuntu#

咱们确实是切换到 root 用户了,然而 shell 环境中的变量并没有扭转,还是用之前 ubuntu 用户的环境变量。

接着咱们从 ubuntu 用户以 login-shell 的形式切换到 root 用户,同样比拟两种用户转台下环境变量中 PWD 的值:

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu                # 是 /home/ubuntu
HOME=/home/ubuntu
# 省略.......
ubuntu@VM-0-14-ubuntu:~$ su -    # 是 login-shell 形式
Password:
root@VM-0-14-ubuntu:~# env | grep root
USER=root
PWD=/root                        # 曾经变成 /root 了
HOME=/root
MAIL=/var/mail/root
LOGNAME=root
root@VM-0-14-ubuntu:~#

能够看到用 login-shell 的形式切换用户的话,shell 中的环境变量也跟着扭转了。

总结:具体应用哪种形式切换用户看集体需要:

  • 如果不想因为切换到另一个用户导致本人在以后用户下的设置不可用,那么用 non-login-shell 的形式;
  • 如果切换用户后,须要用到该用户的各种环境变量(不同用户的环境变量设置个别是不同的),那么应用 login-shell 的形式。
切换到指定用户

后面曾经介绍了,如果 su 命令前面不跟任何 <user_name>,那么默认是切换到 root 用户:

ubuntu@VM-0-14-ubuntu:~$ su -
Password:                     # root 用户的明码
root@VM-0-14-ubuntu:/home/ubuntu#

因为咱们在 1. 筹备工作 局部曾经新建了一个 test_user 用户,并且咱们也晓得 test_user 用户的登录明码(root 用户设置的),咱们就能从 ubuntu 用户切换到 test_user 用户:

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:                 # test_user 用户的明码
$
-c 参数

后面的办法中,咱们都是先切换到另一个用户(root 或者 test_user),在哪个用户的状态下执行命令,最初输出 exit 返回以后 ubuntu 用户。

还有一种形式是:不须要先切换用户再执行命令,能够间接在以后用户下,以另一个用户的形式执行命令,执行完结后就返回以后用户。这就得用到 -c 参数。

具体应用办法是:

su - -c "指令串"           # 以 root 的形式执行 "指令串"

我么看个例子:

ubuntu@VM-0-14-ubuntu:~$ cat /etc/shadow
cat: /etc/shadow: Permission denied     
# ubuntu 用户不能间接查看 /etc/shadow 文件内容

ubuntu@VM-0-14-ubuntu:~$ su - -c "tail -n 4 /etc/shadow"
Password:                      # 输出 root 用户明码
ubuntu:$1$fZKcWEDI$uwZ64uFvVbwpHTbCSgim0/:18352:0:99999:7:::
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$     #执行完马上返回 ubuntu 用户而不是 root 用户

这种执行形式和前面要介绍的 sudo 很像,都是长期申请一下 root 用户的权限。但还是有差别,咱们接着往后看。

sudo 命令介绍及次要用法

首先还是解释下 sudo 命令是什么意思。

sudo 的英文全称是 super user do,即以超级用户(root 用户)的形式执行命令。这里的 sudo 和之前 su 示意的 switch user 是不同的,这点须要留神,很容易搞混。

咱们先介绍 sudo 命令能做什么事件,而后阐明为何能做到这些,以及如何做到这些。咱们开始。

次要用法

咱们在 Linux 中常常会碰到 Permission denied 这种状况,比方以 ubuntu 用户的身份查看 /etc/shadow 的内容。因为这个文件的内容是只有 root 用户能查看的。

那如果咱们想要查看怎么办呢?这时候就能够应用 sudo :

ubuntu@VM-0-14-ubuntu:~$ tail -n 3 /etc/shadow
tail: cannot open '/etc/shadow' for reading: Permission denied      # 没有权限
ubuntu@VM-0-14-ubuntu:~$ sudo !!                                    # 跟两个惊叹号
sudo tail -n 3 /etc/shadow
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$

实例中,咱们应用了 sudo !! 这个小技巧,示意反复下面输出的命令,只不过在命令最后面加上 sudo。

因为我曾经设置了 sudo 命令不须要输出明码,所以这里 sudo !! 就能间接输入内容。如果没有设置的话,须要输出以后这个用户的明码,例如本例中,我就应该输出 ubuntu 用户的登录明码。

两次相邻的 sudo 操作,如果距离在 5min 之内,第二次输出 sudo 不须要从新输出明码;如果超过 5min,那么再输出 sudo 时,又须要输出明码。所以一个比拟省事的办法是设置 sudo 操作不须要明码。前面介绍如何设置。

sudo 除了以 root 用户的权限执行命令外,还有其它几个用法,这里做简略介绍。

切换到 root 用户:

sudo su -

这种形式也能以 login-shell 的形式切换到 root 用户,然而它和 su – 办法是由区别的:

前者输出 sudo su – 后,须要提供以后用户的登录明码,也就是 ubuntu 用户的明码;
后者输出 su – 后,须要提供 root 用户的登录明码。
还有一个命令:

sudo -i

这个命令和 sudo su – 成果统一,也是切换到 root 用户,也是须要提供以后用户(ubuntu 用户)的登录明码。

咱们当初切换到 test_user 用户,尝试显示 /etc/shadow 文件的内容:

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:                                       # test_user 的明码
$ sudo cat /etc/shadow
[sudo] password for test_user:                  # test_user 的明码
test_user is not in the sudoers file.  This incident will be reported.
$

咱们会看到倒数第二行中的谬误提示信息,咱们无奈查看 /etc/shadow 的内容,这是为什么?为什么 ubuntu 能够应用 sudo 然而 test_user 不行呢?

这就波及到 sudo 的工作原理了。

sudo 工作原理

一个用户是否应用 sudo 命令,取决于 /etc/sudoers 文件的设置。

从上一节中咱们曾经看到,ubuntu 用户能够失常应用 sudo,然而 test_user 用户却无奈应用,这是因为 /etc/sudoers 文件里没有配置 test_user。

/etc/sudoers 也是一个文本文件,然而因其有特定的语法,咱们不要间接用 vim 或者 vi 来编辑它,须要用 visudo 这个命令。输出这个命令之后就能间接编辑 /etc/sudoers 这个文件了。

须要阐明的是,只有 root 用户有权限应用 visudo 命令。

咱们先来看下输出 visudo 命令后显示的内容。

输出(root 用户):

root@VM-0-14-ubuntu:~# visudo

输入:

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
ubuntu  ALL=(ALL:ALL) NOPASSWD: ALL
解释下每一行的格局
第一个示意用户名,如 root、ubuntu 等;接下来等号右边的 ALL 示意容许从任何主机登录以后的用户账户;等号左边的 ALL 示意:这一行行首对一个的用户能够切换到零碎中任何一个其它用户;行尾的 ALL 示意:以后行首的用户,能以 root 用户的身份下达什么命令,ALL 示意能够下达任何命令。

咱们还留神到 ubuntu 对应的那一行有个 NOPASSWD 关键字,这就是表明 ubuntu 这个用户在申请 sudo 时不须要输出明码,到这里就解释了后面的问题。

同时咱们留神到,这个文件里并没有 test_user 对应的行,这也就解释了为什么 test_user 无奈应用 sudo 命令。

接下来,咱们尝试将 test_user 增加到 /etc/sudoers 文件中,使 test_user 也能应用 sudo 命令。咱们在最初一行增加:

test_user  ALL=(ALL:ALL)  ALL       
# test_user 应用 sudo 须要提供 test_user 的明码

接下来咱们再在 test_user 账户下执行 sudo:

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:
$ tail -n 3 /etc/shadow
tail: cannot open '/etc/shadow' for reading: Permission denied
$ sudo tail -n 3 /etc/shadow                   # 加上 sudo
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
$

能够看到,当初曾经能够应用 sudo 了。

思考

咱们曾经看到了,如果一个用户在 /etc/sudoers 文件中,那么它就具备 sudo 权限,就能通过 sudo su – 或者 sudo -i 等命令切换到 root 用户了,那这时这个用户就变成 root 用户了,那这不对系统造成很大的威逼吗?

实际上确实是这样的。所以如果在编辑 /etc/sudoers 文件赋予某种用户 sudo 权限时,必须要确定该用户是可信赖的,不会对系统造成歹意毁坏,否则将所有 root 权限都赋予该用户将会有十分大的危险。

当然,root 用户也能够编辑 /etc/sudoers 使用户只具备一部分权限,即只能执行一小部分命令。

二者的差别比照

咱们曾经看到:

  • 应用 su –,提供 root 账户的明码,能够切换到 root 用户;
  • 应用 sudo su –,提供以后用户的明码,也能够切换到 root 用户
  • 两种形式的差别也不言而喻:如果咱们的 Linux 零碎有很多用户须要应用的话,前者要求所有用户都晓得 root 用户的明码,这显然是十分危险的;后者是不须要裸露 root 账户明码的,用户只须要输出本人的账户明码就能够,而且哪些用户能够切换到 root,这齐全是受 root 管制的(root 通过设置 /etc/sudoers 实现的),这样零碎就平安很多了。

个别都是举荐应用 sudo 形式。

你学会了吗?有帮忙的话能够 点个在看、转发朋友圈 反对一下。

起源:https://tanjuntao.github.io/

退出移动版