shell命令以及运行原理
我们来输入指令的本质就是 输入字符串。
而指令的本质,就是编译好的文件和脚本,而只要是文件,就会在系统的特定路径下存放。
我们使用所有的指令最终都要在 OS (操作系统)内部运行,但是 OS 使用难度比较高,我们直接使用 操作系统当中数据 是比较困难的。所以我们用户是不能直接使用 其中 的操作系统的,我们一般使用的都是 图形化界面 or 命令行解释器 这两种来实现 操作系统和 用户的交互。
而在windows当中使用的就是 图形化界面,而且在 LInux当中使用的就是,用的 命令行解释器 来交互。
而 shell 就是 命令行解释器。Shell的最简单定义:
- 命令行解释器(command Interpreter)主要包含:将使用者的命令翻译给核心(kernel)处理。
- 同时,将核心的处理结果翻译给使用者
- 保护OS,对于用户的非法请求,直接拦截
如果我们输入的命令时非法访问 ,或者是 对操作系统当中的不能修改的文件,有修改的操作的,那么上述的 命令行解释器就可以帮我们识别,然后进行 相应的结束或者是提示。这就变相的保护了操作系统。
像上述说的 命令行 命令行解释器 bash sh shell 其实都是一样的。在windows当中 还叫做 图形化界面。
其中的 kernal 就是 Linux 内核。其中的 shell 对我们输入的指令进行解析,将解析的指令传给操作系统;操作系统将运行的结果,通过 shell 解析给用户。
Linux 权限
了解 Linux 当中的 用户分类
在Linux当中的并不说所有的操作都可以 使用的,在 Linux 当中有两种 用户:一种是 root 超级用户;一种是 root 用户新建的 (adduser)用户,叫做普通用户。
超级用户的命令提示符是“#”,普通用户的命令提示符是“$”
而在 Linux 当中有权限的限制,权限就是用来限制 用户进行某些 操作的,root 超级用户不受权限限制;而 普通用户 受到权限的限制。root 可以实现权限限制的操作,从这里来看 Linux当中 管理员的 权限是 比 windows当中的管理员高的;但是也不是就意味着 Linux 当中的 root 用户什么操作都可以实现,比如有些 操作系统正在使用的 文件 root 用户是无法访问的。
而不管是 root 用户还是 普通用户都需要有 各自的密码,只要是用户都是有密码的。
root 用户和 普通用户 之间的切换
其实 root 和 普通用户之间是可以 切换的,如果是 普通用户,使用 su 指令就可以实现切换。
如果现在你正处于某个普通用户当中,输入 su ,然后再输入 root 用户的密码就可以 切换为 root 用户:
我们发现,系统就只提示了 password : 这样的字样,没有提示类似 password for xxx : 这样的字样;那么像 password:这样就是默认是 root 账号的密码,那么由此也就引出一个点,我们一般建议是,不要把 root 账号的和 普通用户的 账号 密码 设置为一样的密码。
如果我们进入了 root 用户想要退回到 之前的 普通用户,那么我们可以 输入 exit 命令 或者是 使用 ctrl + D 热键来退回到之前的普通用户:
我们还可以 使用 su - 这个命令 来从普通用户 登录 到 root 用户:
此时我们发现 相对于 su 命令多了一行 Last login: 的字样,这表示 登入的意思。
也就是说 ,之前的 su 只是用户的切换 ,没有登录 root 用户,只是切换到 root 用户;而 su - 却是 登录到 root 用户。
而 切换 和 登录的区别就是 ,切换只是切换 了用户,切换之后所处的 路径就是切换之前 所处的路径,而 登录之后会所处的路径是在 改用户的家目录下。
如果当前你登录的是 root 用户,那么也可以使用 su 普通用户名 这个命令行来从root 用户切换到对应的 普通用户。
像上述的 例子,我们就从 root 用户切换到 gaobo 这个普通用户了,而且我们发现,没有 对应的password : 的输入,因为如果你是 root 用户,切换到其他普通用户的话,不需要输入密码,想切换到谁就切换到谁。如果我们想 退回到 root 用户,那么我们同样可以使用 crtl + D 或者 输入 exit 命令的方式退回到 root 用户。
我们来做一个比较,从一个 普通用户,像切换到另一个普通用户的话,还是需要输入密码的;
sudo 指令
对一条指令进行提权。
如果我们当前是一个普通用户,但是需要权限来使用 一行命令,又不想切换到 root 用户之下来进行操作,那么我们就可以使用 sudo 指令来实现。
语法:
sudo 需提权指令
有上图,我们可以发现,我们输入的是当前普通用户的密码,当我们输入之后,我们发现我们的权限就是 root 了,而且,在接下来的一段时间内,我们再次接下 sudo 的时候就不用在输入密码了(时间的多少根据系统不同有差别)。
相信看到这里的读者一定有一个疑问,为什么使用 sudo 的时候,我们输入自己普通用户的密码就可以是使用 root 的权限了,这是不是有点扯。
其实,如果我们马上使用 adduser 新建一个普通用户,那么这个普通用户是没有办法使用 sudo 指令的,因为此时系统默认是不信任这个用户的;只有在将来,将这个普通用户添加到系统的信任白名单当中,这样,这个用户才能够使用 sudo 指令。
Linux权限管理
简单来说 ,在 Linux 当中的一件事情是否能被人 而 做,这就是权限做的事情。而去权限其实认证的是 身份,权限和人有关;
权限 也和事物的 “属性” 有关,在Linux当中文件,有什么属性,比如 可读 , 可写 , 可执行等等的属性,这些也都和 权限有关。
我们可以 使用 ls -l 来查看 文件的属性:
我们发现,在文件的属性开头,有这么 由 10个字符组成的一串字符串:
开头的 第一个 字符表示的是 文件类型。
文件的类型
我们在 windows 当中是通过文件名的后缀来 识别这个文件是一个什么文件;但是在 Linux 当中 文件的后缀名没有直接的意义,在 Linux 当中是通过 入下图所示的 第一个字符来表示 文件类型:
不同字符,代表的文件类型:
- d:文件夹
- -:普通文件
- l:软链接(类似Windows的快捷方式)
- b:块设备文件(例如硬盘、光驱等)磁盘文件,如下所示其实就是 磁盘,只不过在Linux当中一切皆是文件。
- p:管道文件 向下述例子就利用 管道文件进行 简单的转移。
- c:字符设备文件(例如屏幕,键盘,显示器等串口设备)
- s:套接口文件
需要注意的是,假设我们写了一段 C 语言源代码,文件名叫 text.c ,当我们 使用 mv text.c text.txt 命令,把这个 文件名改为 text.txt 之后,我们发现,原本能用gcc跑过的 text.c ,修改名字为 text.txt 之后就不能跑了。这是因为 gcc 是一款编译器,是一个 能在 Linux 操作系统上运行的软件,那么这个软件是用 文件名后缀来识别这个文件是什么类型的文件的,所以它跑不过。
针对上述的几种情况, Linux 在看待系统 当中的 文件名后缀时,是不管的,他只看属性当中的字符,所以不管文件是否有后缀,后缀是什么都是不管的。
文件的基本权限
后面的字符表示的意思:
- 读(r/4):Read对文件而言,具有读取文件内容的权限;对目录来说,具有浏览该目录信息的权限
- 写(w/2):Write对文件而言,具有修改文件内容的权限;对目录来说具有删除移动目录内文件的权限
- 执行(x/1):execute对文件而言,具有执行文件的权限;对目录来说,具有进入目录的权限
- “—”表示不具有该项权限(对应的权限位置,没有权限)
那么权限也是要看 “人” 的,比如,校长办公室能不能进,也是要看 “人” 的,那么 “人” 代表的不是 用户,而是 权限身份。
在 Linux 当中 有三种权限身份:
- 拥有者:表示这个文件是属于 谁的
- 所属组:假设在一个 Linux 系统当中 可以同时登录 10个用户,有 6 个用户组成了一个组,那么他们可以给 文件设置 一些 组级别的权限。
- 其他人:表示这个文件不属于谁
在一个文件当中就会有上述 三种 身份的权限规定。
那么这里 三种身份和 之前我们说的 root 和 普通用户有什么区别吗?
其实 root 和 普通用户是 “人”,而且 上述的三种 只是 “人” 扮演的一种身份。也就是说,上述的 三种身份既可以是 root 来扮演,也可以是 普通用户来扮演,如下图所示关系:
所属组身份出现的原因:
举个例子,如果在一个公司当中,有两个工作室 都开发同一个项目,公司像利用这种 方式来实现竞争的目的,从而做出更好的作品。那么 两个工作室当中,假设 张三 和 李四 分别在不同的工作室当中。有一天 张三写了 一段它认为很好的 代码,不想被 李四看到,李四本就属于是 其他人,那么就可以把 其他人 这个身份权限设置为 “0”,这样 李四就 不能读 不能写 不想运行这个文件了。但是如果张三工作室当中 有一个人 ,假设叫 王五,他想看张三写的代码,但是王五属于是 其他人的身份。那么王五就不能看到 张三写的代码,如果把其他人 身份的权限打开,李四就会看到代码,这就矛盾了。
那么为了实现上述的效果,就多设计了一个身份,叫做 所属组,把这个身份 的权限打开,让王五加入 所属组,那么王五就可以看到代码了。
那么在刚才 10个字符表示的文件属性当中,我们说了第一个字符表示的是 文件的类型,那么后面 9 个其实就是 表示的是 该文件 那三个权限身份 所对应 权限属性:
上述的10个字符,除了 第一个字符表示的是文件的类型,后面的 9 个字符,3个 3个 为一组,从左向右 分别表示的是 拥有者 所属组 其他人 这个三种身份的 r-读权限 w-写权限 x-执行权限。
也就是说,在权限的三个位置表示上,每一个位置的权限都是固定的,什么位置是什么含义是固定的,而且每一个位置只有 是 或 否 ,具有指定的权限:
像上述的 test.txt 文件,如果我以 whb 也就是 拥有人的权限来访问的话,我们就有 写 和 读的权限,但是没有执行文件的权限。
比如,现在我们以 一个 不能读,写,执行文件的身份去访问一个文件:
提示 Permission denied。
我们发现他会提示我,不能访问这个文件。
但是,我们知道 root 是不受权限约束的,也就是说,就算 root 是一个不不能读,不能写,不能执行的身份,他也可以实现 读写等等的操作,因为 root 用户不受权限约束。
如下图所示表示的是 这个文件的拥有者:
如下图所示,表示的是,这个文件 的所属组是哪一个:
像上图当中的所属组,因为这个文件就只是自己再用,所以这个文件的所属组就以 当前的用户名在名了,当前用户就是这个组的组长。
如下图表示的是,这个文件的大小(单位是字节):
如下图表示的是,这个文件最近一次修改的时间:
假设我们以 root 的身份访问 上述的 的 test.txt 这个文件,那么Linux会进行身份的对比,如果不是拥有者,也不是所属组,那么就是 其他人。其实在判断的时候 就是 一个 if () else if () else 的逻辑,因为 其他人 这个身份太多了,不能穷举。
权限的修改
使用 chmod u g o 的方式 修改
当我们 创建一个文件之后,我们可以使用 一下命令来对 文件当中权限进行修改:
chmod u-rwx,g-rwx,o-rwx 文件名
上述的 u g o 三个字母分别代表的意思是 : 拥有者 所属组 其他人。
这样就可以把 text.txt 这个文件当中,拥有者,所属组,其他人的所有权限都关闭。
使用一下方式来 对某一个 身份添加一个权限:
chmod u+r test.txt
拥有者增加一个 读的属性。
如下:给拥有者去掉 读的权限。
chmod u-r test.txt
上述就是修改权限的例子。
用8进制来进行修改
我们知道,对于上述权限,每一个位置就代表一个权限,而且只有是 或 否两种表达形式,那么我们就可以想用 用 1 或 0 来表示 是 或 否。比如 rwx 表示为 二进制的 111 ,计算出结果就是 7;rw- 表示为 110 ,计算出结果就是 6,我们发现每一位上的权限可以 对应为8进制的数字从 0 - 7。
那么我们还可以用 chmod 这样写:
把 拥有者 所属组 其他人 的权限都关闭,这里有三个 0 ,每一个 0 代表的是 三个对应关系的 而二进制表达式所计算出的 8 进制结果。
chmod 000 test.txt
修改 文件的 权限身份
可以使用 如下方式把 文件的拥有者 身份给某一个用户:
chown 用户名 文件名
但是,这种操作如果我们直接使用的话吗,应该会报 Permission not permitted 你没有这个权限的错误。
因为我们要给文件的话,需要对方的同意。
如果对方不统一我们也可以使用 sudo 来强制执行。
当我们使用 root 用户给文件拥有者权限的时候,就不需要对方同意了。
可以使用如下的方式把 文件的所属组 给其他:
chgrp 所属组名 文件名
如上所示,就把 所属组给gaobo 这个用户了。
同样 chgrp 和 chmod 一样是需要对方同意的,如果不同意可以使用 sugo 的方式强制给出,或者直接使用 root 账号直接跳过这个权限直接强制给出。
我们还可以一次就把 文件的拥有者和 所属组都进行修改:
chown 拥有者名:所属组名 文件名
如上述,我们把test.txt 文件的拥有者和 所属组 都修改为了 gaobo 那么我们现在就可以一次性把两个权限身份都修改为 whb:
其他注意的点
那么能修改权限的只能是 两种人,一种是文件的拥有者,另一种就是不受权限约束的 root 用户。
关于权限的三个问题
权限身份的认证
如上述情况, whb 是我当前的用户名,那么我即是 文件的拥有者,又是所属组,那么我们当然可以进行 读的操作,但是写的操作 我能不能做呢?
答:不能写。
如果当前用户在 文件当中有多个文件权限身份的时候,只能选择一个身份进行验证,按照从左到有的顺序,如果前面的身份已经被选择了,那么即使后面有可以穿戴的身份Linux也不会管了。
如上述例子,我们把 这个文件的拥有者改成其他人,那么我们就会被认为是 所属组,那么我们就可以进行写的操作。
文件默认权限
如下,是我们新创建的 两个普通文件和 两个目录。
这里就有一个问题,为什么我们新创建的普通文件,和是目录,他的文件权限身份的默认访问权限,回事上述一样的设置:
为什么普通文件是 :664
为什么目录文件是 :775
我们先来了解一下LInux当中给文件的默认权限值:
- 默认给普通文件的起始权限是666;
- 默认给目录的其实权限是777;
但是我们上述的普通文件和目录的默认的权限却不是 666 和 777 。
这是因为,在 Linux 当中有一个叫 权限掩码(umask)的东西:
凡是在 uamsk 当中出现的权限,不会在最终的文件权限中出现。
umask 就像是 筛子一样,显示拿到这个文件的默认权限,然后通过某种计算,把 umask 当中有的权限 从默认权限当中去掉,最后得到的才是像上述一样的 权限。
而像上述当中的 umack 他是 0002 ,其实他就是一个 8 进制的数,第一位可以看做是 代表 8 进制的符号,所以它的值其实就是 002 ,例如上述的普通文件 的默认权限是 666 ,那么二进制就是 : 111 111 111 ,umack 二进制数就是 000 000 010 :
那么在 uamsk 当中出现过的权限,就不应该在 其实权限当中出现了。根据上图,我们得出了 起始权限的最终值: 110 110 100 ,转换成 8 进制就是 664。
那么同样,对于 目录也是一样的:
这里的计算方法其实就是单纯的 没在 umack 当中出现的权限在,默认的权限当中就不会出现,umack 出现的权限,如果在 默认权限当中本来就没有,那么就没有,如下所示:
其实逻辑上,他是按照下述 的公式来进行 计算的:
最终权限 = 起始权限&(~umask)
我们可以采用以下命令来 修改 umask 的值:
umack xxxx (其中 xxx 代表 umask 的值)
Linux 当中的目录 的 读 写 执行 代表什么(目录的权限)
我们都知道,在Linux当中一切皆是文件,那么 目录 也是一个文件,它的 读 写 执行 操作是怎样的呢?
如下例子:
我们首先是 把 dir 这个目录的 所有人的 读 的权限都 删除掉,然后,我们使用 cd 来进入 这个目录,我们发现可以进入,但是我们使用 ls 来查看这个目录当中的文件的时候,就不能 查看,提示 Permission denied;没有权限。
那么我们就发现:
目录的 读 权限 不是阻止用户进入目录的权限,而是 阻止用户查看目录当中的文件列表的权限。
再如下例子:
我们进入先把这个目录的 写 权限删除了,然后我们进入这个目录,发现是能进入的,然后我们使用 touch 想创建创建一个 txt 的文件,发现还是 报错: Permission denied;没有权限。
目录的 写 权限,控制用户 是否能在当前目录下进行 创建,更改,删除文件的操作。
但是上述当中的删除操作,有点不一样,我们在下一个小标题(目录权限)当中进行讲解。
目录的 执行 权限,控制用户是否能 进入 该目录。
如上述例子,把目录的 权限改为 可读可写,不可执行,我们 cd dir ,发现报错了。
我们这里来查看一些 Linux 当中用户 home 目录的 权限:
我们发现,上述当中的 每一个用户的家目录的权限都是 700 ;也就是说 只有 这个目录的拥有者 才有 读写执行权限,而 其他所属组 , 其他人 的都是没有任何权限的。
那么,Linux 当中的用户是肯定需要 进行 文件的交互的,所以当我们 想 跟 其他用户 进行交互的时候,我们需要在根目录下,创建 一个 文件夹,再在这个文件夹当中,放入我们想要共享的文件,然后设置这个文件夹的 访问权限。
现在,假设我把上述当中 用于共享的文件夹的权限都是打开的,但是,我们惊奇的发现,其他用户竟然能够 删除 我用于共享的这个目录当中的 这个普通用户没有任何权限的文件!!
比如上述例子,我们使用 gaobo 这个用户,删除掉了 whb 用户创建的 共享目录当中的文件,而且这个文件, gaobo 是没有权限 进行 读写 和执行的。
其实,在Linux 当中 一个文件是否能被 用户删除,不是这个文件所决定的,而是由 这个文件所在目录 决定的。
如果我们把这个共享目录 的 w (写)权限 去掉了,那么其中的文件,其他的 用户就不能进行 删除操作了。
但是,上述提到了 去除 w(写)这个权限,但是这个目录又是一个 共享文件,其他用户怎么,往这个目录当中创建 文件呢?
所以,我们使用上述,修改 共享目录 的权限,使得 其他用户不能删除目录当中 的 文件是不可取的。
我们查看 根目录 的权限,发现 other 是不能写的 ,只能读:
那么也就是说,普通用户 一般是不能在 根目录下 创建共享目录的,只能由 root 用户创建,那么对于 root 用户创建的共享目录,那么所有的用户都属于是 other 。其实也没有必要创建共享目录,我们ls 查看 根目录,发现有一个 tmp 的目录,这个目录是唯一一个 在 根目录下 带 t (粘滞位) 的目录。
粘滞位
为了解决 上述的关于 共享文件的一些 问题,我们引入了 粘滞位这个概念,这个一般是给目录设置的,设置之后,大家可以在这个目录当中进行 增 改 查;只允许 文件拥有者或者是 root 用户 类删除这个文件,其他人一概不允许。
t 是 一种 特殊的 x 权限,例子如下:
如上述,给 共享目录当中的 other ,加一个 粘滞位。
当我们给 这个共享目录 的 other 设置 粘滞位 之后,向上述 当中的 gaobo 用户删除 whb 用户创建的文件就不行了: