本文基础参考文档:
这个在线文档也能看看:
Linux学习教程,Linux入门教程(超详细) (biancheng.net)
不过有些章节要收费,可以复制标题到百度搜索,一般都会有。
更详细的看鸟哥的书:
如果文档有不理解的地方,可以找个视频看看,比如:
基础内容,直接查阅文档即可,本文重点记录容易搞错容易忘记的地方。
Linux源码和文档
linux内核的源码:The Linux Kernel Archives
Linux的API手册
首页 - 《Linux API速查手册》 - 书栈网 · BookStack
接口列表:
Linux manual pages: all pages, by section (man7.org)
Linux基本上是兼容Posix标准的。
更多待补充。
Linux重要目录
linux目录结构如下所示:
Linux 系统目录结构 | 菜鸟教程 (runoob.com)
bin目录补充:
可以看到,全是命令对应的可执行文件。
linux中bin目录是什么 Linux系统中标准目录/bin的作用 全网首发(图文详解1) - 无名阁无名阁
dev目录补充:
就是设备文件放置的地方,注意,设备文件和驱动并不是同一概念,设备文件可以看做是用来访问对应设备驱动的一个入口。
Linux /dev目录详解和Linux系统各个目录的作用 - core! - 博客园 (cnblogs.com)
[请教]/dev下面有几十个tty的文件,每个都有用吗? - Linux新手园地-Chinaunix
etc目录补充:
/etc :系统主要配置文件几乎都放置在这个目录内,如用户账号、密码、各种服务起始文件等、该目录下的文件普通用户可以查看,但只有root用户有权修改。FHS建议不要放置可执行文件(binary)在此目录。
该目录下比较重要的文件有:
/etc/inittab、/etc/init.d/、/etc/modprobe.conf、/etc/X11/、/etc/fstab、/etc/sysconfig
该目录下重要的目录有:
/etc/init.d/: 所有服务的默认启动脚本都是放置在这里的。
例如启动或关闭iptables命令为:
/etc/init.d/iptables start //启动
/etc/init.d/iptables stop //关闭
lib目录补充:
lib: 放置的是在系统开机时用到的函数库,以及在/bin或/sbin下面的命令会调用到的函数库而已。/lib/modules/这个目录下放置内核相关的驱动程序。
opt和usr目录补充:
linux系统/opt目录和/usr/local目录有什么区别_opt文件夹是什么意思-CSDN博客
proc目录补充:
Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。
用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。
详解linux系统下/proc文件夹目录_proc文件夹 gpu-CSDN博客
这些数字是进程ID,都对应着具体的进程。
更多补充:
文件挂载
主要涉及到mount命令。
mount命令的功能是将文件系统挂载到目录。文件系统指的是被格式化过的硬盘或分区设备,进行挂载操作后,用户便可以在挂载目录中使用硬盘资源了。
语法格式:mount 参数 设备名 目录名
举例:
Linux系统启动过程
可参考:
rcS里面是自启动的一些程序,区分自启动和手动执行,其他的一些程序就需要手动执行。
Linux命令的执行过程
可参考:
文件类型
Linux 系统下,可以通过 stat 命令或者 ls 命令来查看文件类型
stat 命令非常友好,会直观把文件类型显示出来;对于 ls 命令来说,并没有直观的显示出文件的类型,而是通过符号表示出来,在图 5.1.2 中画红色框位置显示出的一串字符中,其中第一个字符( ' - ' )就用于表示文件的类型,减号' - ' 就表示该文件是一个普通文件;除此之外,来看看其它文件类型使用什么字符表示:普通文件是最常见的文件类型;目录也是一种文件类型;设备文件对应于硬件设备;符号链接文件类似于 Windows 的快捷方式;管道文件用于进程间通信;套接字文件用于网络通信。Linux 下一切皆文件,文件作为 Linux 系统设计思想的核心理念,在 Linux 系统下显得尤为重要。注意:Linux 系统下,一切皆文件,也包括各种硬件设备。设备文件(字符设备文件、块设备文件)对应的是硬件设备,虽然有设备文件,但是设备文件并不对应磁盘上的一个文件,也就是说设备文件并不存在于磁盘中,而是由文件系统虚拟出来的,一般是由内存来维护,当系统关机时,设备文件都会消失;字符设备文件一般存放在 Linux 系统/dev/目录下,所以/dev 也称为虚拟文件系统 devfs。
文件属主
Linux 是一个多用户操作系统,系统中一般存在着好几个不同的用户,而 Linux 系统中的每一个文件都有一个与之相关联的用户和用户组,通过这个信息可以判断文件的所有者和所属组。
文件所有者表示该文件属于“谁”,也就是属于哪个用户。一般来说文件在创建时,其所有者就是创建该文件的那个用户。譬如,当前登录用户为 dt,使用 touch 命令创建了一个文件,那么这个文件的所有者就是 dt;同理,在程序中调用 open 函数创建新文件时也是如此,执行该程序的用户是谁,其文件所有者便是谁。
文件所属组则表示该文件属于哪一个用户组。在 Linux 中,系统并不是通过用户名或用户组名来识别不同的用户和用户组,而是通过 ID。ID 就是一个编号,Linux 系统会为每一个用户或用户组分配一个 ID,将用户名或用户组名与对应的 ID 关联起来,所以系统通过用户 ID(UID)或组 ID(GID)就可以识别出不同的用户和用户组。
Tips:用户 ID 简称 UID、用户组 ID 简称 GID。这些都是 Linux 操作系统的基础知识,如果对用户和用户组的概念尚不熟悉,建议先自行学习这些基础知识。
譬如使用 ls 命令或 stat 命令便可以查看到文件的所有者和所属组,如下所示:
检查文件权限access
文件的权限检查不单单只讨论文件本身的权限,还需要涉及到文件所在目录的权限,只有同时都满足了,才能通过操作系统的权限检查,进而才可以对文件进行相关操作;所以,程序当中对文件进行相关操作之前,需要先检查执行进程的用户是否对该文件拥有相应的权限。那如何检查呢?可以使用 access 系统调用,函数原型如下:#include <unistd.h> int access(const char *pathname, int mode);
函数参数和返回值含义如下:pathname : 需要进行权限检查的文件路径。mode : 该参数可以取以下值:⚫ F_OK :检查文件是否存在⚫ R_OK :检查是否拥有读权限⚫ W_OK :检查是否拥有写权限⚫ X_OK :检查是否拥有执行权限除了可以单独使用之外,还可以通过按位或运算符 " | " 组合在一起。返回值: 检查项通过则返回 0 ,表示拥有相应的权限并且文件存在;否则返回 -1 ,如果多个检查项组合在一起,只要其中任何一项不通过都会返回-1 。简单示例如下:
软链接和硬链接
在 Linux 系统中有两种链接文件,分为软链接(也叫符号链接)文件和硬链接文件,软链接文件也就是前面给大家的 Linux 系统下的七种文件类型之一,其作用类似于 Windows 下的快捷方式。那么硬链接文件又是什么呢?本小节就来聊一聊它们之间的区别。
首先,从使用角度来讲,两者没有任何区别,都与正常的文件访问方式一样,支持读、写以及执行。那它们的区别在哪呢?在底层原理上,为了说明这个问题,先来创建一个硬链接文件,如下所示:
Tips:使用 ln 命令可以为一个文件创建软链接文件或硬链接文件,用法如下:
硬链接:ln 源文件 链接文件
软链接:ln -s 源文件 链接文件
关于该命令其它用法,可以查看 man 手册。
从图 5.7.1 中可知,使用 ln 命令创建的两个硬链接文件与源文件 test_file 都拥有相同的inode 号,既然inode 相同,也就意味着它们指向了物理硬盘的同一个区块,仅仅只是文件名字不同而已,创建出来的硬链接文件与源文件对文件系统来说是完全平等的关系。那么大家可能要问了,如果删除了硬链接文件或源文件其中之一,那文件所对应的 inode 以及文件内容在磁盘中的数据块会被文件系统回收吗?事实上并不会这样,因为 inode 数据结结构中会记录文件的链接数,这个链接数指的就是硬链接数,struct stat 结构体中的st_nlink 成员变量就记录了文件的链接数,这些内容前面已经给大家介绍过了。
当为文件每创建一个硬链接,inode 节点上的链接数就会加一,每删除一个硬链接,inode 节点上的链接数就会减一,直到为 0,inode 节点和对应的数据块才会被文件系统所回收,也就意味着文件已经从文件系统中被删除了。
从图 5.7.1 中可知,使用"ls -li"命令查看到,此时链接数为 3(dt 用户名前面的那个数字),我们明明创建了 2 个链接文件,为什么链接数会是 3?其实源文件 test_file 本身就是一个硬链接文件,所以这里才是 3。当我们删除其中任何一个文件后,链接数就会减少,如下所示:
接下来再来聊一聊软链接文件,软链接文件与源文件有着不同的 inode 号,如图 5.7.3 所示,所以也就是意味着它们之间有着不同的数据块,但是软链接文件的数据块中存储的是源文件的路径名,链接文件可以通过这个路径找到被链接的源文件,它们之间类似于一种“主从”关系,当源文件被删除之后,软链接文件依然存在,但此时它指向的是一个无效的文件路径,这种链接文件被称为悬空链接,如图 5.7.4 所示。
从图中还可看出,inode 节点中记录的链接数并未将软链接计算在内。
介绍完它们之间的区别之后,大家可能觉得硬链接相对于软链接来说有较大的优势,其实并不是这样,对于硬链接来说,存在一些限制情况,如下:
⚫ 不能对目录创建硬链接(超级用户可以创建,但必须在底层文件系统支持的情况下)。
⚫ 硬链接通常要求链接文件和源文件位于同一文件系统中。
而软链接文件的使用并没有上述限制条件,优点如下所示:
⚫ 可以对目录创建软链接;
⚫ 可以跨越不同文件系统;
⚫ 可以对不存在的文件创建软链接。
system函数
使用 system()函数可以很方便地在我们的程序当中执行任意 shell 命令,本小节来学习下 system()函数的用法,以及介绍 system()函数的实现方法。
首先来看看 system()函数原型,如下所示:#include <stdlib.h> int system(const char *command);
这是一个库函数,使用该函数需要包含头文件<stdlib.h>。
函数参数和返回值含义如下:
command:参数 command 指向需要执行的 shell 命令,以字符串的形式提供,譬如"ls -al"、"echo HelloWorld"等。
system()函数其内部的是通过调用 fork()、execl()以及 waitpid()这三个函数来实现它的功能,首先 system()会调用 fork()创建一个子进程来运行 shell(可以把这个子进程成为 shell 进程),并通过 shell 执行参数command 所指定的命令。譬如:system("ls -la") system("echo HelloWorld")
system()的返回值如下:
⚫ 当参数 command 为 NULL,如果 shell 可用则返回一个非 0 值,若不可用则返回 0;针对一些非UNIX 系统,该系统上可能是没有 shell 的,这样就会导致 shell 不可能;如果 command 参数不为NULL,则返回值从以下的各种情况所决定。
⚫ 如果无法创建子进程或无法获取子进程的终止状态,那么 system()返回-1;
⚫ 如果子进程不能执行 shell,则 system()的返回值就好像是子进程通过调用_exit(127)终止了;
⚫ 如果所有的系统调用都成功,system()函数会返回执行 command 的 shell 进程的终止状态。
system()的主要优点在于使用上方便简单,编程时无需自己处理对 fork()、exec 函数、waitpid()以及 exit()等调用细节,system()内部会代为处理;当然这些优点通常是以牺牲效率为代价的,使用 system()运行 shell命令需要至少创建两个进程,一个进程用于运行 shell、另外一个或多个进程则用于运行参数 command 中解析出来的命令,每一个命令都会调用一次 exec 函数来执行;所以从这里可以看出,使用 system()函数其效率会大打折扣,如果我们的程序对效率或速度有所要求,那么建议大家不是直接使用 system()。一般情况下均可使用。
补充
Bash也是一种编程语言。
C语言编译成可执行文件后可以在linux上执行,但是bash是解释性的脚本语言,可以直接在linux上执行,无需编译。
linux内核的源码:The Linux Kernel Archives
swp文件
解决Linux Shell脚本错误:“/bin/bash^M: bad interpreter: No such file or directory”-CSDN博客
使用vi/vim,经常可以看到swp这个文件,那这个文件是怎么产生的呢,当你打开一个文件,vim就会生成这么一个.(filename)swp文件,当vim异常退出时,就会将内容备份到该文件中,如果你正常退出,那么这个这个swp文件将会自动删除 。
注意区分chown和chmod
chown 函数chown 是一个系统调用,该系统调用可用于改变文件的所有者(用户 ID )和所属组(组 ID )chmod 函数chmod 是一个系统调用,在 Linux 系统下,可以使用 chmod 命令修改文件权限。
Linux命令长选项"--"和短选项"-"和没有"-"选项区别(选项的单双连字符'-'和'--'区别)_linux命令行为什么需要长选项和短选项-CSDN博客
后台运行程序
有没有办法既能让 hello 正常运行,而且终端能够正常使用?那肯定是有的,让 hello 进入后台运行就行了,让一个软件进入后台的方法很简单,运行软件的时候加上“&”即可,比如“./hello &”就是让 hello 在后台运行。在后台运行的软件可以使用“kill -9 pid(进程 ID)”命令来关闭掉,首先使用“ps”命令查看要关闭的软件 PID 是多少,ps 命令用于查看所有当前正在运行的进程,并且会给出进程的 PID。
进程的环境变量
每一个进程都有一组与其相关的环境变量,这些环境变量以字符串形式存储在一个字符串数组列表中,把这个数组称为环境列表。其中每个字符串都是以“名称=值(name=value)”形式定义,所以环境变量是“名称-值”的成对集合,譬如在 shell 终端下可以使用 env 命令查看到 shell 进程的所有环境变量,如下所示:
使用 export 命令还可以添加一个新的环境变量或删除一个环境变量:
export LINUX_APP=123456
# 添加 LINUX_APP 环境变量
使用"export -n LINUX_APP"命令则可以删除 LINUX_APP 环境变量。
export -n LINUX_APP
# 删除 LINUX_APP 环境变量
环境变量的作用
环境变量常见的用途之一是在 shell 中,每一个环境变量都有它所表示的含义,譬如 HOME 环境变量表示用户的家目录,USER 环境变量表示当前用户名,SHELL 环境变量表示 shell 解析器名称,PWD 环境变量表示当前所在目录等,在我们自己的应用程序当中,也可以使用进程的环境变量。