Welcome to 9ilk's Code World

(๑•́ ₃ •̀๑) 个人主页: 9ilk
(๑•́ ₃ •̀๑) 文章专栏: Linux网络编程

🏠 shell命令以及运行原理
📌 引入例子理解shell

假设八里村有一个人叫张三,他的父亲是这个村的村长。张三喜欢隔壁的如花,但是张三本人不擅长交际,却想跟如花谈恋爱结婚,于是希望村里的王婆帮其说媒。 在这个场景下,我们的张三相当于是用户,而如花相当于是系统内核,王婆相当于是外壳程序(kernel),张三想让王婆帮他和如花说媒相当于是用户想访问系统内核,需要通过指令让外壳程序帮我们返回内核。
Linux严格意义上说的是一个操作系统,我们称之为"核心(kernel)",但我们一般用户,不能直接使用kernel。而是通过kernel的"外壳"程序,也就是所谓的shell,来与kernel沟通。

📌 shell三问
- Q1 : 为什么需要外壳程序?
在上面这个例子中,张三不擅长跟人交流,需要王婆帮助他解释他的需求给如花。对应的,用户不擅长也无法直接访问内核,他需要外壳程序解释他的需求。
因此广义上Linux系统 = Linux内核 + 外壳程序。
而技术角度shell的最简单定义是命令行解释器,它包括:
-
将使用者的命令翻译给核心(kernel)处理。
-
同时将核心的处理结果翻译给使用者。
在这里shell这个命令行解释器就相当于王婆,将指令(也就是张三的要求)解释给内核(如花)。
注 :
1.对比Windows GUI,我们操作windows不是直接操作windows内核,而是通过图形接口,点击,从而完成我们的操作。(比如我们进入D盘的操作通常是通过双击D盘盘符)。
2.shell对于Linux,有相同的作用,主要是对我们的指令进行解析,解析指令给Linux内核。反馈结果再通过内核运行出结果,通过shell解析给用户。
- Q2 :shell是如何进行指令解释的?
我们故事继续,王婆知道如花不喜欢张三,但是迫于张三的父亲是村长,怕自己说媒不成功丢了招牌,因此不管说媒结果如何都要办这件事,于是王婆决定成立说媒公司,她通过招实习生来帮助她给张三说媒,这样即使说媒没成功也可以说是实习生干的,同时不会丢了她自己的招牌。
从这个故事我们可以类比理解,其实外壳程序shell是通过创建子进程,让子进程来帮忙进行命令解释,以此来保证自身的安全和稳定性。
- Q3 : Shell和Bash是什么关系?
王婆她是个媒婆,媒婆是她们这一行的统称,而王婆是一个具体的媒婆;类比理解,其实王婆相当于是bash,而媒婆就是shell外壳。
也就是说,我们对不同平台的外壳程序统称为shell,它是包在操作系统外面的一个软件层,而Linux的外壳程序叫bash。
🏠 理解Linux权限
📌 一个认识
假设你是张三,是一个学校的校长,你能在学校活动发表讲话是因为你此时的身份是学校校长,而张三这两个字对你而言代表你是一个具体的人 ,校长代表的是你的角色/身份。
我们需要认识到:我们在现实生活什么可为什么不可为是由我们的身份/角色决定的。类似的,你在Linux系统中能做什么不能做什么也是由你的身份决定的。
📌 Linux下的用户
- Linux下分为两种用户:超级用户和普通用户。
超级用户:可以在Linux系统下做任何事情,不受限制。
普通用户:在Linux下做有限的事情。
超级用户的命令提示符是"#",而普通用户的命令提示符是"$"。

- 用户之间的切换
1. 普通用户->超级用户
bash
su -
su root
su
注 : 由于超级用户权限大因此切换到root时需要输入密码 。同时切换之后如果想退到上次登录可以使用ctrl + d和exit。

2. 超级用户->普通用户
bash
su user

注 : 由于超级用户权限大,因此切换到普通用户不需要输入密码。
- 普通用户提权操作
若我们想让普通用户能使用一些超级用户才能使用的指令或想不切换为root用户而使用root权限做某些事,此时我们可以使用提权操作。
bash
sudo + 命令

但是注意普通用户需要切换成root加进**相关配置文件(/etc/sudoers
)**才能用sudo进行超级用户权限执行。
bash
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
tommy ALL=(ALL) ALL
在ubuntu系统使用sudo提权可能会出现这样错误:

此时可以先切换到root输入如下指令,将用户名添加到sudoers文件:
bash
sudo adduser image sudo //image是你要恢复的用户名
然后su image切回到在使用的用户就可以正常使用了。

- 新建用户
bash
adduser + 新建用户名 //新建用户
passwd + 用户名 //设置密码
🏠 Linux权限管理
📌 文件权限
📒 文件访问者的分类(人)
1. 文件和文件目录的所有者 : u --- User。
2. 文件和文件目录的所有者所在的组的用户 : g --- Group。
3. 其他用户 :o --- Others。

- Q1 : 为什么other没有被列出来呢?
对于文件,拥有者只有一个人,所属组只有一组,而other可以是多人不需要再列出,而且也没必要列出,因为不是拥有者和所属组就是other。
- Q2 :为什么文件访问者需要所属组?

假设张三和李四两个好朋友进入同一个公司且由于团队赛马,他们两分进了同一个项目,但是并未分进同一个组,张三在A组,李四在B组,哪组的成果比较好谁的成果就会被在项目上实施。A组组长让张三写了一个code.c,有一天组长想查看张三的代码进度,此时只有拥有者张三和other 两个访问权限,想让组长看就只能让other也能看,但这样难免会被B组偷窥,因此我们需要一个所属组访问者分类,让A组的人都能看到。
由此我们可以理解到,所属组是为了进行更细粒度的权限管理。
- Q3 : 如何理解权限与访问者的关系?
所谓权限其实就是等于人 + 事物的属性。
比如我们程序员喜欢在leetcode上刷算法题,但是你不能在leetcode上看电影,为什么?那是因为leetcode这个网站没有对应的属性。也就是说,即使我是拥有者但是事物没有对应属性也是白费力气,即使这个事物有对应属性但是我的人所处的角色没有办法使用这些属性也是白搭。
同样的,常见的文件有读(r) , 写(w) , 执行(x)三种权限,权限 = 人 + 事物属性,我们的用户相当于是一个具体的人,而拥有者,所属组以及other是我们这些人在不同文件中扮演的不同角色,用户在文件中的权限就是看你这个用户在这个文件扮演的角色是否能使用这个文件对应的属性!

📒 文件类型和返回权限(事物属性)
在Linux中我们可以使用ll命令查看文件的相关属性:

- 文件类型
d:文件夹
-:普通文件l:软链接(类似Windows的快捷方式)
b:块设备文件(例如硬盘、光驱等)
p:管道文件
c:字符设备文件(例如屏幕等串口设备)
s:套接口文件
- 基本权限
i.读(r/4):Read对文件而言,具有读取文件内容的权限;对目录来说,具有浏览该目录信息的权限。
ii.写(w/2):Write对文件而言,具有修改文件内容的权限;对目录来说具有删除移动目录内文件的权限。
iii.执行(x/1):execute对文件而言,具有执行文件的权限;对目录来说,具有进入目录的权限。
iv."---"表示不具有该项权限。
- Q1 : 如何描述一个文件?

描述文件从人和属性来描述,比如对于这个file.txt文件它对应的拥有者有可读可写不可执行权限,所属组有只读权限,其他用户只有可读权限。
- Q2 : 如何进行身份认证?

假如对于zqh这个普通用户它对于test.txt这个文件,它不是拥有者,也不是所属组,那他就是other,他就只能读文件。
注意:在进行身份认证时,只认证一次,认证顺序是拥有者,所属组,other前一个验证失败,才到下一个。

比如对于file.txt它的所属组和拥有者是file.txt,但是所属组有写权限,拥有者没有,当对zhuang用户进行身份认证时从左到右是将它认证成拥有者,因此他对于file.txt这个文件并没有写权限!
- 理解x(执行)权限

为什么对于main和file.txt他们都有x权限,但是一个可执行一个不可执行呢?
那是因为可执行权限和文件能不能执行无关,一个文件要被执行需要:1.具有可执行权限。2.本身是个可执行文件。
📒 文件权限的更改

我们怎么更改权限呢?
我们知道权限 = 人 + 属性 ,那么更改权限要么从角色入手要么从文件权限属性入手。比如对于zhuang用户要想对file读写,要么将拥有者修改为zhuang,要么更改他作为other的文件权限s属性。
✈️ 从属性入手
chmod
功能 : 设置文件的访问权限
格式 : chmod [参数] 权限 文件名
常用选项 : -R 递归修改目录文件的权限。
- chmod + u/g/o/a +/- rwx组合 + 文件名
字符说明:
- u/g/o/a :
u表示拥有者
g表示所属组
o表示other
a表示所有用户
- +/- :
+表示向权限范围增加权限代号所表示的权限
-表示向权限范围取消权限代号所表示的权限
注 : 可以一次性对多个角色进行权限更改,但是要用逗号隔开。

- 使用八进制:chmod 八进制 文件名
- 只有文件的拥有者和root才能改变文件的权限。

- 对于普通文件即使root是所属组且文件属性显示没有对应权限,它也能进行相关操作。

✈️ 从角色入手
1. chown
功能 : 修改文件的拥有者
格式 : chown [参数] 用户名 文件名
bash
# chown user1 f1
# chown -R user1 filegropu1
2. chgrp
功能 : 修改文件或目录的所属组
格式 : chgrp [参数] 用户组 文件名
常用选项:-R 递归修改文件或目录的所属组
- 更改拥有者必需切换到原有的拥有者;更改所属组要么切换到原有所属组,要么切换到其拥有者。

但是注意对于root用户它可以无视上面规则:

- 普通用户在改变所属组/拥有者时需要sudo提权或者切换成root用户。

普通用户把文件给别人需要征求别人同意,而root可以强制给。
📌 目录权限
- 目录的可读权限
如果目录没有可读权限,则无法使用ls等命令查看目录中的文件内容。

- 目录的可写权限:如果目录没有可写权限,则无法在目录中创建文件/目录,也无法在目录中删除文件/目录。

拓展:我们可以得到一个文件的新建删除并不取决于这个文件的本身读写权限,而是取决于所在目录给它的权限。因此Linux系统里普通用户一般默认无法进入到另一个普通用户的家目录里,如果进入且在里面新建文件目录也没事,因为这个目录拥有者可以删除。

- 目录的可执行权限:如果没有可执行权限,则无法cd到目录中。

📒 权限掩码

为什么我们新建一个目录的默认权限是775,新建一个文件默认权限是664?其实不然。
最终权限 = 起始权限 & (~权限掩码)
其实目录的起始权限是777,普通文件的起始权限是666;当起始权限按位与权限掩码的取反时(二进制运算)才得到文件/目录的最终权限!
比如:起始权限是666 -> 110 110 110;umask为244 -> 010 100 100取反得到101 011 011
因此最终权限为100 010 010 也就是422
怎么查对应的权限掩码呢?
bash
umask
将现有的存取权限减去权限掩码后,即可产生建立文件时预设权限。超级用户默认掩码值为0022,普通用户默认为0002。


怎么修改对应的权限掩码呢?
bash
umask 044//修改权限掩码

权限掩码有什么意义呢?
假设一个开发团队在同一个系统上工作,系统管理员可以设置一个合适的umask值,比如002,用来确保新文件和目录默认允许组内其他成员读取和写入,但禁止其他用户访问.这种设置可以有效的支持团队协作,同时保护文件 不被其他不相关用户访问。
🏠 file指令
功能 : 辨识文件类型。
语法 :file [选项] 文件/目录

常用选项:
- -c : 详细显示指令执行过程,便于排错或分析程序执行的情形。

- -z :尝试去解读压缩文件的内容。
🏠 粘滞位
- 加上粘滞位操作 : chmod +t 文件/目录

- 当一个目录/文件被设置成"粘滞位",则该目录下的文件只能由
1. 超级管理员root删除
2. 该目录的所有者删除
3. 该文件的所有者删除

需求:在一个目录下要求任何人都能进去新建文件/目录等,但不允许删除别人文件和文件夹时可以使用粘滞位。
总结:
1.shell是我们的指令解释器,是用户和内核之间沟通的桥梁。
2.Linux权限 = 人 + 事物属性,描述文件也要从人跟事物属性谈。
3.文件和目录对应的读写执行权限含义不同。
4.更改文件权限可以从角色入手(chown chgrp),也可以从属性入手(chmod)。
5.最终权限 = 起始权限 & ~(权限掩码)。