1【Linux】入门 (权限的理解||umask||粘滞位||c&&c++程序的翻译过程||解释性语言和编译性语言的区别)

发布时间:2024年01月15日

无废话,全干货

一.权限

1.基本权限

读(r): Read 对文件而言,具有读取文件内容的权限;对目录来说,具有浏览该目录信息的权限。
写(w): Write 对文件而言,具有修改文件内容的权限;对目录来说具有删除移动目录内文件的权限。
执行(x): Execute 对文件而言,具有执行文件的权限;对目录来说,具有进入目录的权限。

2.注意点

1.Linux不以文件后缀区分文件类型(并不代表不可以使用),通过ll显示的第一列的字符表明文件类型
d:目录 -:普通文件 p:管道文件 b:块设备 c:字符设备
2.剩下九个字符三三为一组,分别是拥有者,所属组,其他人的权限。

3.操作权限

3.1chmod

功能:设置文件的访问权限
使用:一次性操作多个目标权限中间加逗号

chmod g-r 文件名
chmod u+rwx 文件名
chmod a-x 文件名 (所有人)

3.2chown||chgrp

sudo chown 用户名 文件名
sudo chgrp 用户名 文件名

3.3.umask

其实,Linux 规定了目录的起始权限是 777,而普通文件的起始权限是 666。除了起始权限,Linux 系统还有一个权限掩码,超级用户默认掩码值为0022,普通用户默认为0002。(注:最开头的 0 不需要管,可以看做八进制数的标志)系统默认会配置好 umask 权限码。凡是在 umask 权限掩码中出现的权限,都必须在起始权限中去掉。

umask 数字 //将权限掩码改为指定数字

最终权限=起始权限&(~umask)

4.目录的权限

可执行权限: 如果目录没有可执行权限,则无法 cd 到目录中。
可读权限: 如果目录没有可读权限,则无法用 ls 等命令查看目录中的文件内容。
可写权限: 如果目录没有可写权限,则无法在目录中创建文件, 也无法在目录中删除文件。

5.粘滞位

当在一个公共文件夹下操作文件时,其他人没有任何权限却可以删除文件。因为能不能删除文件取决于该用户对于该目录有没有读权限。公共目录对于任何人都有读写执行权限。所以任何人都能删除其他人在公共目录下的文件。那这样是不合理的。所以就有了粘滞位的概念(粘滞位只能给目录进行设置

chmod +t 目录名 

当一个目录被设置为 “粘滞位”(chmod +t),则该目录下的文件只能由 超级管理员删除 该目录的所有者删除 该文件的所有者删除

二.程序的翻译过程

1.编译性语言和解释性语言

我们知道像c/c++/c#这类语言是编译性语言,而python/java等语言是解释性语言。那么什么事编译和解释呢?

编译是将源程序翻译成可执行的目标代码,翻译与执行是分开的;而解释是对源程序的翻译与执行一次性完成,不生成可存储的目标代码。这只是表象,二者背后的最大区别是:对解释执行而言,程序运行时的控制权在解释器而不在用户程序;对编译执行而言,运行时的控制权在用户程序。
简单来说,编译性语言要通过编译汇编生成一个二进制的目标文件(将高级语言转为汇编再转为机器),然后链接生成可执行。而解释性语言是在运行时将程序翻译和执行,不生成目标代码,逐条解释源程序。

解释具有良好的动态特性和可移植性,比如在解释执行时可以动态改变变量的类型、对程序进行修改以及在程序中插入良好的调试诊断信息等,而将解释器移植到不同的系统上,则程序不用改动就可以在移植了解释器的系统上运行。同时解释器也有很大的缺点,比如执行效率低,占用空间大,因为不仅要给用户程序分配空间,解释器本身也占用了宝贵的系统资源。
编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;
而解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的.

Java很特殊,Java程序也需要编译,但是没有直接编译称为机器语言,而是编译称为字节码,然后在Java虚拟机上用解释方式执行字节码。Python 的也采用了类似Java的编译模式,先将Python程序编译成Python字节码,然后由一个专门的Python字节码解释器负责解释执行字节码。摘自博客园某佬

2.c/c++的翻译过程

2.1预处理

去注释,宏替换,头文件展开,条件编译等等。预处理之后还是c语言文件。

1预处理器(cpp)将所有的#define删除,并且展开所有的宏定义。
2处理所有的条件预编译指令,比如#if、#ifdef、#elif、#else、#endif等。
3处理#include预编译指令,将被包含的文件直接插入到预编译指令的位置。
4删除所有的注释。
5添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
6保留所有的#pragma编译器指令,因为编译器需要使用它们。
7使用gcc -E hello.c -o hello.i命令来进行预处理, 预处理得到的另一个程序通常是以.i作为文件扩展名

2.2.编译

编译器(ccl)将预处理完的文本文件hello.i进行一系列的词法分析、语法分析、语义分析和优化,翻译成文本文件hello.s。(符号表的形成也在这个时候)

词法分析:扫描器(Scanner)将源代的字符序列分割成一系列的记号(Token)。lex工具可实现词法扫描。
语法分析:语法分析器将记号(Token)产生语法树(Syntax Tree)。yacc工具可实现语法分析(yacc: Yet Another Compiler Compiler)。
语义分析:静态语义(在编译器可以确定的语义)、动态语义(只能在运行期才能确定的语义)。
源代码优化:源代码优化器(Source Code Optimizer),将整个语法书转化为中间代码(Intermediate Code)(中间代码是与目标机器和运行环境无关的)。中间代码使得编译器被分为前端和后端。编译器前端负责产生机器无关的中间代码;编译器后端将中间代码转化为目标机器代码。
目标代码生成:代码生成器(Code Generator).
目标代码优化:目标代码优化器(Target Code Optimizer)。

2.3.汇编

汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中,hello.o是一个二进制文件。

一个程序从功能上可以划分为多个模块,每一个功能模块可以独立编程,每一模块的程序也可以独立编译,此时,生成得到的目标文件,称为可重定位目标文件,其代码和数据可以和其他可重定位目标文件合并

2.4.链接

hello程序调用了printf函数,它存在于一个名为printf.o的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到我们的hello.o程序中。连接器(ld)就负责处理这种合并。结果就得到了hello文件,它是一个可执行目标文件(或者称为可执行文件),可以被加载到内存中,由系统执行。(链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件)。

参考程序详细编译过程(预处理、编译、汇编、链接)
参考1.2 认识可重定位目标文件和可执行目标文件
点赞支持!!!

文章来源:https://blog.csdn.net/m0_73865858/article/details/135588645
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。