Linux下用户、群组、权限操作
以Debian系为例
在描述用户、群组、权限之前,先简述一下文件的权限:
在Linux下,一切皆文件,一个文件具有三种权限,分别是读( r | 4)、写( w | 2)、执行( x | 1 ),我们可以通过chmod
命令规定哪些人可以对该文件执行哪些操作,也就是权限;我们可以使用+/-
号配合r/w/x
来分别赋权,也可以使用数字之和进行赋权,比如我想赋权执行权限,我可以使用chmod 111 a.sh
来让所有用户可执行该文件。
因此root用户或该用户的持有者可以规定该文件可以被那些人执行,一般来说分为三类人:我(u)、跟我同组的人(g)、其他人(o),以上的三种人可以统称为「所有人」(a)。我们可以通过chmod [u/g/o/a][+/-][w/r/x] filename
的方式规定特定用户对某一文件的执行权限,而上述举例中111
的意思分别代表[本人/跟我同组的人/其他所有人],我用第一个1给我执行权限,第二个1代表与我同组的人可执行该文件,第三个1代表其他所有人都可以执行该文件。该命令还可以被chmod +xxx a.sh
来代替。
举例:如果想所有人对a.sh
文件读写执行权限,可以执行chmod 777 a.sh
注意,默认情况下写权限>读权限,如果我只对一个文件赋予写权限,那么同时我也获得了它的读权限(尽管在查看权限中不会显示),但是依旧可以查看该文件。
我们可以通过ls -l
命令查看一个文件的具体权限,部分发行版支持ll
(ls -l命令的缩写)命令直接查看权限。
1. 「 👩💻 用户 」的创建、修改与删除
useradd [可选参数] username # 创建用户
usermod [可选参数] username # 修改用户信息
userdel [可选参数] username # 删除用户
注意:对用户进行操作的时候一定要保证以命令开头,以用户名结尾,可选参数放中间。
另外:新创建的用户如果不指定shell的话,我们在执行su username
进入到该用户命令行下是,是指显示一个$
的,这明显是错误的所以一定要指定shell(比如-s /bin/bash
)
更新内容:可以通过id username/userid
的方式查看用户的详细信息
1.1 😈 命令解读: useradd
| 添加用户
命令解读
该命令一共有如下可选参数:
-c
<备注> 加上备注文字。备注文字会保存在passwd的备注栏位中
-d
<登入目录> 指定用户登入时的起始目录
-D
变更预设值
-e
<有效期限> 指定帐号的有效期限
-f
<缓冲天数> 指定在密码过期后多少天即关闭该帐号
-g
<群组> 指定用户所属的群组
-G
<群组> 指定用户所属的附加群组
-m
制定用户的登入目录
-M
不要自动建立用户的登入目录
-n
取消建立以用户名称为名的群组
-r
建立系统帐号
-s
指定用户登入后所使用的shell
-u
指定用户ID
- 在大多数Linux及其发行版中,都会要求我们在登录时创建用户(部分发行版甚至默认不允许使用root用户登录),登录之后我们会进入一个目录,如果是Desktop版本会有像是Windows一样的Desktop、Documents、Download等目录,Server版本中则是什么都没有,这样的文件一般存放在
/home/username
。因此我们在创建用户的时候可以通过useradd -d /home/username username
命令来指定用户的home文件。- 若是不存在该目录则会报错,这时候我们若是手动
mkdir
,则会比较麻烦,可以通过增加-m
参数来创建该目录,命令useradd -d -m /home/username username
。- 若是我们没有使用
-s
来指定用户所使用的shell,那么我们在su username
进入到该用户的命令行下时,则只会显示一个$
符号(而不是像其他用户一样显示username@hostname
这样),我们可以使用-s
参数指定用户的shell来解决这个问题,比如useradd -s /bin/bash
username
下面会举一些例子,来帮助理解
(用户名为jimx
)
useradd jimx # 添加一般用户
useradd -g root jimx # 为添加的用户指定相应的用户组
useradd -r jimx # 创建一个系统用户
useradd -d /home/jimx jimx # 为新添加的用户指定home目录
useradd -u 544 jimx # 建立用户且制定ID
useradd -d /home/jimx -m -s /bin/bash # 建立用户并制定shell
扩展
添加一个不能登录的用户
useradd -d /usr/local/apache -g apache -s /bin/false apache
要拒绝系统用户登录,可以将其 shell 设置为 /usr/sbin/nologin 或者 /bin/false
usermod -s | --shell /usr/sbin/nologin username
# 或者
usermod -s | -shell /bin/false username
说明及比较:
/bin/false
用户会无法登录,并且不会有任何提示。
/usr/sbin/nologin
会礼貌的向用户显示一条信息,并拒绝用户登录:This account is currently not available.
有一些软件,比如一些 ftp 服务器软件,对于本地非虚拟账户,只有用户有有效的 shell 才能使用 ftp 服务。这时候就可以使用 nologin 使用户即不能登录系统,还能使用一些系统服务,比如 ftp 服务。/bin/false 则不行,这是二者的重要区别之一。
/etc/nologin
如果存在该文件文件,则系统只允许 root 用户登录,其他用户全部被拒绝登录,并向他们显示 /etc/nologin 文件的内容(ssh或者Desktop登录都会被拒绝,但是不会将已经登录的用户挤下去,同时root用户或已登录用户还可以使用su username
的方式登录其他用户)。
1.2 😈 命令解读: usermod
| 修改用户信息
usermod
命令的参数与useradd
一致,如果创建用户时信息出现了问题或环境问题出现变化需要给用户新的权限或群组等,都可以使用usermod
命令,因此不做过多介绍,举几个🌰吧。
usermod -s /bin/sh jimx # 将jimx的shell修改为`/bin/sh`
usermod -d /home/jimx2 -m jimx # 创建并将jimx的home目录修改为`/home/jimx2`
usermod -g sudo jimx # 将jimx添加到root群组
1.3 😈 命令解读: userdel
| 删除用户
删除用户非常简单userdel username
命令即可删除,但是若是用户处于登录状态下则不会被删除,userdel
命令有一些参数,如下:
-f
:强制删除 ( 用户在登录状态下不会被删除,但是一旦登出立即删除 )-r
:删除用户的同时删除用户的home文件
举个🌰:
userdel jimx # 删除jimx用户,若是用户已经登录(ssh、terminal或是su)则会进行以下提示:
# userdel: user jimx is currently used by process 146xx
userdel -f jimx # 删除jimx用户,若是用户正忙则依旧报上面的提示,用户一旦退出登录则立即删除
userdel -d jimx # 删除jimx用户,同时删除jimx的home文件(本例中为`/home/jimx`)
2. 「 👨👩👧👦 群组 」的创建、修改与删除
群组与用户的命令几乎一致,都是通过group[add/mod/del] [可选参数] groupname来对组进行创建/修改/删除的。
在Linux中,用户是属于分组的,我们可以指定用户是属于某一分组,然后同时为该分组确定某种权限以达到群体性赋权的效果。
2.1 😈 命令解读: groupadd
| 创建分组
groupadd [可选参数] 用户组
groupadd [-g gid [-o]] [-r] [-f] group
-g
:指定新建工作组的 id;
-r
:创建系统工作组,系统工作组的组 ID 小于 500;
-K
:覆盖配置文件 /etc/login.defs;
-o
:允许添加组 ID 号不唯一的工作组。
-f
,–force: 如果指定的组已经存在,此选项将失明了仅以成功状态退出。当与 -g 一起使用,并且指定的GID_MIN 已经存在时,选择另一个唯一的 GID(即 -g 关闭)。
我们可以用过cat /etc/group
来查看群组-用户关系
举些🌰:
注意:群组id是可重复的(加-o
即可),但是群组名称不可重复
groupadd xx # 创建一个普通的群组,群组id为已存在的最大群组id+1
groupadd -g 10086 newgroup # 创建一个群组并指定id为10086,若该群组id已存在则创建失败并报错,可以通过下面的命令解决
groupadd -o -g 10086 group2 # 创建一个名为group2的群组,并且允许id重复,与上面的分组一致都为10086,没有任何输出信息直接创建成功
2.2 😈 命令解读: groupmod
| 修改分组
若是创建分组时信息有误或随着环境变化该分组的信息也需要改变,就可以使用
groupmod
命令来修改分组信息,修改分组与修改用户(usermod)相似,只不过所加的可选参数有区别,如下:
-g
: --gid | 将组 ID 改为 GID
-h
: --help | 显示此帮助信息并推出
-n
: --new-name | 改名为 NEW_GROUP
-o
: --non-unique | 允许使用重复的 GID
-p
: --password | 将密码更改为(加密过的) PASSWORD
因为groupmod
与usermod
命令相似,可以;理解互通,因此只举几个例子:
groupmod -g 10088 group # 将group的id设置为10088
groupmod -n group newgroup # 将newgroup重命名为group
groupmod -p 123 group # 给group群组设置密码为123
在Linux中,group密码是一个用于限制对group访问权限的措施。当一个group有一个密码时,只有那些知道该密码的用户才能够加入该group。这种措施可以帮助管理员确保只有经过授权的用户才能够加入某些group,从而保护系统的安全性。
需要注意的是,group密码是可选的,不是所有的group都需要设置密码。通常只有在需要限制对特定group的访问权限时才会设置group密码。例如,在一个公司内部的电子邮件系统中,可能会创建一个只有特定员工才能够访问的group,这时可以设置一个group密码来确保只有经过授权的员工才能够访问该group。
在Linux中,group密码存储在/etc/gshadow文件中,只有root用户和属于shadow组的用户才有权限访问该文件。通过设置正确的文件权限和用户组,管理员可以确保group密码的安全性。
2.3 😈 命令解读: groupdel
| 删除分组
groupdel [可选参数] groupname
-R
: --root CHROOT_DIR directory to chroot into [这个参数查询了很多资料都没有找到,希望大佬们多多指点]
-P
:–prefix PREFIX_DIR prefix directory where are located the /etc/* files [这个参数查询了很多资料都没有找到,希望大佬们多多指点]
-f
: --force | 强制删除分组,即使组内有用户也会删除,用户会回归到无分组状态
一般来说直接group group
就可以,但是若是组内存在用户则可能会报groupdel: cannot remove the primary group of user 'username'
groupdel groupname # 删除一个群组
groupdel -f group # 强制删除,忽略是否存在用户
3. 权限管理:chmod
、chown
与chgrp
命令
看命令的名称可以看出来,chmod='change mode’修改模式(权限模式)、chown=‘change owner’(修改所有者)、chgrp=‘change group’(修改分组),其他的就迎刃而解啦。
3.1 😈 命令解读:chmod
| 修改文件权限
如一开始介绍的那般,我们可以使用
chmod [可选参数] filename
文件设置权限,权限分别对应着读r(4)写w(2)可执行x(1)
,可以使用rwx或数字及数字之和赋权:
rwx = 4 + 2 + 1 = 7
rw = 4 + 2 = 6
rx = 4 +1 = 5
chmod命令具有以下可选参数
-c
:–changes | 若该档案权限确实已经更改,才显示其更改动作
-f
:–silent | 若该档案权限无法被更改也不要显示错误讯息
-v
: --verbose | 显示权限变更的详细资料
--no-preserve-root do not treat ‘/’ specially (the default)
--preserve-root fail to operate recursively on ‘/’
--reference=RFILE use RFILE’s mode instead of MODE values
-R
: --recursive | 以递归的方式对目前目录下的所有档案与子目录进行相同的权限变更(对文件夹使用,若是
不加-R则只修改该文件夹的权限,加上-R修改所有子文档的权限,一般来说许多命令都是用-r
来表示递
归,但是由于在chmod中-r
也代表去掉读权限的意思,因此要严格使用-R
)
--help
: 显示此帮助信息
--version
: 显示版本信息
权限设定字串,详细格式如下 :
[ugoa…][[±=][rwxX]…][,…],
u
(user)表示该档案的拥有者,g
(group)表示与该档案的拥有者属于同一个群体者,o
(other)表示其他以外的人,a
(all)表示所有(包含上面三者)。
[±=] (尽在rwx时使用,不可对数字使用)
表示增加权限,- 表示取消权限,= 表示唯一设定权限。
[rwxX]
r
表示可读取,w
表示可写入,x
表示可执行,X
表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
举个🌰:
# 对所有用户赋权
chmod ugo+r a.conf
或
chmod a+r a.conf
chmod 777 a.sh # 对所有用户赋予读写执行权限
# ↑ 等价于 `chmod ugo+rwx a.sh` 或 `chmod u=rwx,g=rwx,o=rwx` 或 `chmod ugo+r,ugo+w,ugo+x a.sh`
chmod 600 a.sh # 对用户持有者赋予读写权限,同组及非同组的其他人不给任何权限
# ↑ 等价于`chmod u=rw,g=---,o=--- a.sh` 或 `chmod u=rw,go-rwx file`
chmod a+r,ug+w,o-w a.sh b.sh # 设置文件 a.sh 与 b.sh 权限为拥有者与其所属同一个群组 可读写,其它组可读不可写
chmod -R u+x a # 对a这个文件夹及其所有子文件(或文件夹)赋予执行权限
3.2 😈 命令解读:chown
| 更改文件所有权
chown [可选项] user/username[:group] file…
以上命令[方括号]中的内容为可选项,其余为必写项
user
: 新的文件拥有者的使用者 ID
group
: 新的文件拥有者的使用者组(group)
-c
: 显示更改的部分的信息
-f
: 忽略错误信息
-h
:修复符号链接
-v
: 显示详细的处理信息
-R
: 处理指定目录以及其子目录下的所有文件
--help
: 显示辅助说明
--version
: 显示版本
我们可以使用username
或userid
来更改用户的所有权,比如我用jim
这个账号创建的a.sh,我想将所有权给jimx,我可以执行下面的命令:
chown jimx a.sh # 或
chown 1006 a.sh # 1006为jimx的用户id,我们可以在创建用户的时候指定id或chmod改变用户id,若是创建的时候不做任何操作则会在已存在的最大id上+1,可以通过`cat /etc/group`下查看用户id,如果你觉得全部输出太繁琐的话,可以使用`cat /etc/group | grep username`的方式进行过滤
1006为jimx的用户id,我们可以在创建用户的时候指定id或chmod改变用户id,若是创建的时候不做任何操作则会在已存在的最大id上+1,可以通过cat /etc/group
下查看用户id,如果你觉得全部输出太繁琐的话,可以使用cat /etc/group | grep username
的方式进行过滤
chown -R jim:root a # 以递归的方式将a文件夹及其子文件的所有权给root分组下的jim用户
3.3 😈 命令解读:chgrp
| 更改所属分组
chgrp [选项][组群][文件|目录]
chgrp命令 用来改变文件或目录所属的用户组。该命令用来改变指定文件所属的用户组。其中,组名可以是用户组的id,也可以是用户组的组名。文件名可以 是由空格分开的要改变属组的文件列表,也可以是由通配符描述的文件集合。如果用户不是该文件的文件主或超级用户(root),则不能改变该文件的组。
在UNIX系统家族里,文件或目录权限的掌控以拥有者及所属群组来管理。您可以使用chgrp指令去变更文件与目录的所属群组,设置方式采用群组名称或群组识别码皆可。
-R
递归式地改变指定目录及其下的所有子目录和文件的所属的组
-c
或——changes:效果类似“-v”参数,但仅回报更改的部分;
-f
或–quiet或——silent:不显示错误信息;
-h
或–no-dereference:只对符号连接的文件作修改,而不是该其他任何相关文件;
-H
如果命令行参数是一个通到目录的符号链接,则遍历符号链接
-R
或——recursive:递归处理,将指令目录下的所有文件及子目录一并处理;
-L
遍历每一个遇到的通到目录的符号链接
-P
不遍历任何符号链接(默认)
-v
或——verbose:显示指令执行过程;
--reference=<参考文件或目录>
:把指定文件或目录的所属群组全部设成和参考文件或目录的所属群组相同;
chgrp -R group a.sh # 将a.sh的分组改为group
📜 参考资料
「菜鸟教程/runoob」:Linux useradd 命令
「菜鸟教程/runoob」:Linux chown 命令
「CSDN」:Linux权限详解(chmod、600、644、700、711、755、777、4755、6755、7755)
拓展
由于我常用的是Debian系的其他发行版而非Debian系统本身,因此我常用ll
命令代替ls -l
,在Debian系居然没有ll
命令,因此可以在终端中执行alias ll='ls -l'
,以用ll
直接代替ls -l
;这样的方式只会在此终端生效,在其他终端不生效,关闭该终端后也会立即失效,因此可以直接把该命令写到环境变量中来达到永久生效的效果。