目录
1、shell命令
我们在Linux操作系统中输入命令后就可以执行命令,这些命令是 shell 帮我们执行的。shell 实际上是系统当中的一条指令,位于 /usr/bin 目录下。
[root@iZuf69tfiox41j76yf0416Z lesson4]# ls /usr/bin/bash -al
-rwxr-xr-x. 1 root root 964608 Oct 31 2018 /usr/bin/bash
当我们在远程登录到云服务器或者在本机打开终端时,服务器或终端会给我们关联上这样一个 bash 程序,它是一个 命令行解释器,我们称之为 shell 。
我们作为一名用户,在使用 Linux 的过程中不是直接访问 Linux 内核的,而是访问 Linux 外包裹的软件层,这个软件层就是 shell ,被称为 外壳程序 ,也就是同学们现在所感受到的 命令行 。
我们把指令写入到命令行,命令行把指令进行解释并传递给操作系统,操作系统处理完命令之后把结果通过shell返回给用户。
因为用户本身不善于直接对操作系统进行操作,所以才有了 shell 的出现。shell 的存在有以下两点意义:
- 对命令进行解释传递和返回结果
- 保护操作系统:如果输入的是非法指令,则 shell 直接进行拦截,不会传递给操作系统。
bash 是 centos 上的 外壳程序 ,而 shell 是 外壳程序 的统称。
2、Linux权限
2.1、权限的概念
首先,权限是限制人的,其次,所访问的对象需要具有可操作的 "属性" 。比如我们不能在书本上运行代码,因为书本本身就不具备运行代码的 "属性" 。
所以一件事情是否允许被执行,取决于 人 与 事物属性。即 权限 = 用户 + 事物属性 。
在 Linux 操作系统中,用户 分为两种:
- root,超级管理员 —— 几乎可以做任何事情
- 普通用户,具有诸多权限限制
在 Linux 操作系统中,文件属性 有三种:
- 读
- 写
- 执行
2.2、用户操作
用户可以通过指令 whoami 来确认自己的身份
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ whoami
ljb
2.2.1、用户切换
su [用户] 不加用户默认切换到 root 用户
从普通用户切换成 root 用户
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ whoami
ljb
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ pwd
/root/lll/lesson4
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ su
Password:
[root@iZuf69tfiox41j76yf0416Z lesson4]# whoami
root
[root@iZuf69tfiox41j76yf0416Z lesson4]# pwd
/root/lll/lesson4
输入 root 的密码之后,我们就切换成了 root 用户,且我们所处的路径没有发生变化。
如过我们想退出 root 用户,按下 Ctrl + d 可以退出
[root@iZuf69tfiox41j76yf0416Z lesson4]# whoami
root
[root@iZuf69tfiox41j76yf0416Z lesson4]# exit
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ whoami
ljb
su - [用户] 不加用户默认切换到 root 用户
从普通用户切换成 root 用户
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ whoami
ljb
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ pwd
/root/lll/lesson4
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ su -
Password:
Last login: Tue Jan 10 14:14:15 CST 2023 on pts/1
[root@iZuf69tfiox41j76yf0416Z ~]# whoami
root
[root@iZuf69tfiox41j76yf0416Z ~]# pwd
/root
输入 root 的密码后,我们发现不只是用户的身份变了,我们所处的路径也变换到了 root 的家目录。
所以 su 与 su - 的区别在于 su 是让用户再同一个 bash 下进行身份切换,而 su - 是让 root 重新登录
2.2.2、用户提权
sudo 指令提权,让普通用户使用单条指令时暂时拥有 root 用户的权限
如果未来我们作为 普通用户 需要做一些事情,而没有对应的权限,就需要对单条指令进行提权。
为了方便大家更直观的理解,我先把文本文件 test.c 的权限改成禁止所有人访问,之后我们再去打印该文本中的内容就会被权限拒绝。
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ cat test.c
cat: test.c: Permission denied
我们使用 sudo 对该单条指令进行提权
[ljb@iZuf69tfiox41j76yf0416Z lesson4]$ sudo cat test.c
[sudo] password for ljb:
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
在输入 sudo 密码之后,就可以把 test.c 内的文本打印出来了
2.3、文件属性
使用 ls -l 指令查看当前目录所有文件的详细属性时,我们可以发现在文件名前面还跟着许多内容,这些内容分别代表什么意思呢?
[root@iZuf69tfiox41j76yf0416Z lesson4]# ls -l
total 8
-rw-r--r-- 1 root root 0 Jan 10 11:57 cmd.txt
drwxr-xr-x 2 root root 4096 Jan 10 11:57 dir
-rw-r--r-- 1 root root 0 Jan 10 11:57 hello.c
-rw-r--r-- 1 root root 142 Jan 10 11:56 temp.tgz
-rw-r--r-- 1 root root 0 Jan 10 11:51 test.c
这些字符的含义如下图所示:
后面的这几个文件属性理解起来比较简单,我不再过多解释,我主要说明一下前几个文件属性
2.3.1、文件类型
第 1 位字符表示文件类型。在 Linux 操作系统下,不用文件后缀来区分文件类型,而是用文件属性中第一列的第一个字符来区分文件类型,文件类型有:
- :普通文件:文本文件、可执行文件、归档文件等
d :目录
b :块设备:磁盘
c :字符设备:键盘、显示器
p :管道文件
s :网络socket文件
l :连接文件
既然 Linux 不使用文件后缀来区分文件类型,那么我们该如何看待后缀呢?
1、后缀名可以给用户看,方便用户区分文件的类型
2、将后缀当作文件名的一部分
下面举一个例子,我们使用 gcc 对文本文件 test.c 进行编译,形成一个可执行程序 a.out ,执行 a.out:
[root@iZuf69tfiox41j76yf0416Z lesson4]# nano test.c
[root@iZuf69tfiox41j76yf0416Z lesson4]# gcc test.c
[root@iZuf69tfiox41j76yf0416Z lesson4]# ll
total 24
-rwxr-xr-x 1 root root 8440 Jan 10 13:33 a.out
-rw-r--r-- 1 root root 0 Jan 10 11:57 cmd.txt
drwxr-xr-x 2 root root 4096 Jan 10 11:57 dir
-rw-r--r-- 1 root root 0 Jan 10 11:57 hello.c
-rw-r--r-- 1 root root 142 Jan 10 11:56 temp.tgz
-rw-r--r-- 1 root root 69 Jan 10 13:33 test.c
[root@iZuf69tfiox41j76yf0416Z lesson4]# ./a.out
hello world
我们把 a.out 重命名为 a.txt ,再执行一遍:
[root@iZuf69tfiox41j76yf0416Z lesson4]# mv a.out a.txt
[root@iZuf69tfiox41j76yf0416Z lesson4]# ll
total 24
-rwxr-xr-x 1 root root 8440 Jan 10 13:34 a.txt
-rw-r--r-- 1 root root 0 Jan 10 11:57 cmd.txt
drwxr-xr-x 2 root root 4096 Jan 10 11:57 dir
-rw-r--r-- 1 root root 0 Jan 10 11:57 hello.c
-rw-r--r-- 1 root root 142 Jan 10 11:56 temp.tgz
-rw-r--r-- 1 root root 71 Jan 10 13:34 test.c
[root@iZuf69tfiox41j76yf0416Z lesson4]# ./a.txt
hello world
发现程序依然可以执行,且结果没有发生任何变化。
但是,如果我们把 test.c 的后缀改成 .txt,再使用 gcc 对 test.txt 进行编译会发生什么?
[root@iZuf69tfiox41j76yf0416Z lesson4]# mv test.c test.txt
[root@iZuf69tfiox41j76yf0416Z lesson4]# ll
total 24
-rwxr-xr-x 1 root root 8440 Jan 10 13:34 a.txt
-rw-r--r-- 1 root root 0 Jan 10 11:57 cmd.txt
drwxr-xr-x 2 root root 4096 Jan 10 11:57 dir
-rw-r--r-- 1 root root 0 Jan 10 11:57 hello.c
-rw-r--r-- 1 root root 142 Jan 10 11:56 temp.tgz
-rw-r--r-- 1 root root 71 Jan 10 13:34 test.txt
[root@iZuf69tfiox41j76yf0416Z lesson4]# gcc test.txt
test.txt: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
[root@iZuf69tfiox41j76yf0416Z lesson4]#
发现仅仅是把文本文件的后缀从 .c 改为 .txt 后,gcc 再对该文件编译就直接报错了,提示文件无法被识别,这是不是与我们之前得出的 文件类型与后缀无关 的结论相悖呢?
这是因为我们说的是 Linux 下不用文件后缀来识别文件类型。这个 Linux 下,指的是操作系统看待文件不以文件后缀来识别文件,而不代表 gcc 这个软件看待文件也不以后缀来识别文件。所以 操作系 统不关心文件后缀,并不代表操作文件的 软件 不关心。
除了看文件属性的第一个字母外,我们也可以通过 file 指令来获取文件的类型。
file [选项] 文件或目录:
常用选项:
-c 详细显示指令执行过程,便于排错或分析程序执行的情形。
-z 尝试去解读压缩文件的内容
2.3.2、文件权限
对于 Linux 文件的访问者可以分为三类:
- 文件拥有者:文件和文件目录的拥有者 user,简称 u
- 文件所属组:文件和文件目录的拥有者所在的组里的用户 group,简称 g
- 其他人:其他用户 other,简称 o
如图位置显示的是拥有者和所属组,其他人不显示。
第一列的第 2 ~ 10 个字符,每三个字符为一组,第一组代表拥有者权限,第二组代表所属组权限,第三组代表其他人权限。每组的三个字符的顺序与含义是确定的:
- r :拥有可读权限
- w:拥有可写权限
- x:拥有可执行权限
- - :没有该位置所对应的权限
比如我们想要描述文件 a.txt 的权限,可以这样说:拥有者可读可写可执行,所属组可读可执行,其他人可读可执行,拥有者是 root ,所属组是 root 。权限 = 人 + 事物属性。
2.3.3、更改文件权限
因为权限 = 人 + 事物属性,所以我们 修改权限 也可以分为修改 文件权限 与修改 文件拥有者和所属组 。
我们先来学习 修改文件权限 的方法。
修改一个文件权限的前提是当前用户是该文件的拥有者或 root。
chmod [参数] [权限] [文件名] :修改文件权限。
方法一、chmod [用户±权限] [文件名]
chmod u/g/o/a ± rwx filename
例如:
给文件 test.txt 的拥有者(u)添加了读写(rw)权限。
给目录 dir 的所属组(g)减少了可执行(x)权限。
给文件 test.txt 所有访问者(a)都添加了可执行(x)权限。
方法二、chmod [八进制方案] [文件名]
我们可以把对应位置上有权限看作 1 ,没有权限看作 0,从而使用八进制数来表示权限。比如 拥有者权限是 rwx ,对应 111,则八进制数为 7,所属组权限是 --x,对应 001,则八进制数为 1。
例如:
把文件 test.txt 的权限改为 拥有者、所属组、其他人 都 可读可写可执行。
把文件 test.txt 的权限改为 拥有者、所属组、其他人 都 不可读不可写不可执行
root 用户不受权限约束,权限只约束普通用户
接下来我们再来学习修改 文件拥有者和所属组 的方法:
chown 用户名 文件名 :修改文件的拥有者
chgrp 用户名 文件名 :修改文件的所属组
chown 用户名:用户名 文件名:同时修改文件的拥有者和所属组
常用选项:
-R:递归修改文件或目录的所属组
注意,把文件从一个 拥有者A 给到另一个 拥有者B,需要取得 拥有者B 的同意!拥有者A 是 root 用户的情况下除外。
使用 普通用户 把目录 mydir 的拥有者从 普通用户 改为 root ,操作不被允许。
使用 root 用户 把文件 cmd.txt 的拥有者从 root 改为 普通用户,修改成功。
2.3.4、默认权限与权限掩码
我们新创建一个 普通文件 和一个 目录文件 ,观察他们的默认权限
为什么我们创建的 普通文件(不包括可执行)默认权限是从 664 开始的,而 目录 的默认权限是 775 开始的?(不同的操作系统,默认权限可能不同)
这里需要补充两个概念:
- 起始权限 —— 系统设定的权限
- 最终权限 —— 最终我们看到的权限
一般普通文件的起始权限是从 666(rw-rw-rw-) 开始的,目录文件的起始权限是从 777(rwxrwxrwx) 开始的。系统为了更好的控制文件权限,系统会有默认的 权限掩码(umask) 的概念。
掩码可以理解为 用来提取二进制数字中某段区域数字 的 一段二进制序列。比如想从 1011 1010 中提取出后四位,可以使用 1011 1010 & 0000 1111 = 0000 1010。其中 0000 1111 就是掩码。
在Linux 系统中,权限掩码默认为 0002,第一个 0 代表 8 进制(还有其他用途,同学们先不必管),002 为权限掩码的码值,转为二进制就是 000 000 010。
我们最终看到的 默认权限,就是通过特定方法计算出的 最终权限。
最终权限 = 起始权限 & (~umask)
我们可以通过以下指令改变 umask 的值
umask [数值]:把 umask 改为指定数值
2.4、目录的权限
目录的权限同样有三种:
- 可执行权限:如果目录没有可执行权限, 则无法 cd 到目录中。
- 可读权限:如果目录没有可读权限, 则无法用 ls 等命令查看目录中的文件内容。
- 可写权限:如果目录没有可写权限, 则无法在目录中 创建文件 , 也无法在目录中 删除文件。
根据目录权限的概念,只要用户具有 目录 的写权限,用户就可以删除 该目录 中的 文件 ,而不论这个用户是否有这个 文件 的写权限。
可以看到,虽然 普通用户ljb 并没有文件 del.txt 的任何权限,但是还是成功删除了该文件,因为 ljb 拥有该文件所在目录的写权限。
比如 张三 在目录中创建了一个文件,而 李四 却可以随意的删除 张三 的文件,这很不合理。
因此,我们引出了 粘滞位 的概念。
粘滞位出现的背景:在我们使用 Linux 的时候,我们可能要编写一些程序放到一个公共的目录下,被所有人共享。所有人都可以在这个公共的目录下创建属于自己的文件,而如果想要赋予所有用户在该目录下创建文件的权限,同时也就赋予了所有用户在该目录下删除文件的权限。为了避免出现删除别人的文件的情况出现,才出现了 粘滞位。
这个共享的目录通常是 root 提供的,我先来做一些准备工作:
切换到 root 用户,进入到根目录下创建一个 公共目录 pubilc:
进入 公共目录public ,创建几个文件:
切换回 普通用户,试着删除刚刚 root用户 创建的文件,发现确实可以删除:
现在我们切换成 root 用户给公共目录 public 加上粘滞位:
chmod +t [目录] :给指定目录加上粘滞位,粘滞位只给目录添加。
再用 普通用户 删除 公共目录public 里 root用户 创建的文件试一试:
可以看到此时,我们作为 普通用户 且 非该文件拥有者 的情况下,已经无法再删除别人的文件了。
通过粘滞位,我们不仅保证了所有人都可以在公共目录下创建文件,还保证了所有用户都不能随便删除别人的文件。
当一个目录被设置为"粘滞位"(用chmod +t),则该目录下的文件只能由
- 超级用户删除
- 该目录的所有者删除(一般来说 公共目录 的 所有者 就是 超级用户)
- 该文件的所有者删除
关于目录权限的补充:
目录的 可执行权限(x) 是表示你可否在目录下执行命令,如果目录没有 x 权限,则无法对目录执行任何命令,甚至无法 cd 进入目录,即使目录仍然有 r 读权限(这个地方很容易犯错,认为有读权限就可以进入目录读取目录下的文件)。而如果目录具有 x 权限,但没有 r 权限,则用户可以执行命令,可以 cd 进入目录。但由于没有目录的 读 权限所以在目录下,即使可以执行 ls 命令,但仍然没有权限读出目录下的文档。
关于 Linux 下基本权限的内容就全部讲完了,希望同学们多多支持,如果有不对的地方欢迎大佬指正,谢谢!