Linux系统构成与shell核心知识

一、Linux系统的构成

从功能的角度来看,Linux系统主要由两个核心部分构成:

1) 系统调用接口

这一部分主要负责与上层应用程序进行交互,为应用程序提供了一系列的接口,以便它们能够请求系统的服务。

 

2) 内核

内核是系统的核心,负责与下层的硬件设备进行通信,管理硬件资源,并处理所有来自应用程序的请求。值得注意的是,应用程序本身无法直接操作硬件,任何对硬件的操作请求都必须通过操作系统来完成。

操作系统具有两种不同的工作状态:

1) 用户态

在用户态下,操作系统运行的是系统接口代码,主要处理与应用程序的交互和请求。

 

2) 内核态

在内核态下,运行的是系统的内核代码,此时操作系统直接与硬件打交道,处理底层的硬件操作和系统资源管理。

从文件的维度来看Linux操作系统源于ISO镜像文件,而镜像文件本质上是一个包含了一系列系统文件的压缩包。这些文件主要分为两大类:

1) bootfs

在系统启动前起作用,包含启动所需的文件以及内核文件(如/boot/vmlinuz),确保系统能够正确引导。

 

2) rootfs

在系统启动后发挥作用,是整个文件系统的根基,本质上由大量的文件夹和文件组成。

在文件夹和磁盘分区之间存在一种关联关系:

文件夹类似于水龙头,而磁盘分区则是水源的存放地。一个磁盘就像一个水桶,对磁盘进行分区相当于在水桶中创建隔断,为不同的数据和程序提供独立的空间。

在容器技术中,每个容器内部都运行着一个独立的系统,这个系统同样由bootfs和rootfs两部分组成。当使用镜像启动容器时,镜像中必然包含了这两个部分以确保容器内的系统能够正常运作。

二、Linux系统的启动过程详解及进程与程序的关系

程序与进程的概念:

程序本质上是一系列代码文件的集合。这些文件本身是静态的,只有在执行时才会展现出其意义。当一个程序被激活并执行时,便形成了一个进程。

进程是程序运行的动态过程,可以将其视为一个正在执行的程序。进程不仅表示程序的运行,还体现了操作系统对程序运行过程的管理,因此,进程是操作系统核心概念之一。

Linux系统的启动顺序:

系统加电,BIOS(基本输入输出系统)首先启动。
BIOS负责检测并定位启动盘。
BIOS从启动盘的第一块扇区读取MBR(主引导记录),其中包含bootloader程序,并将该程序加载到内存中执行。一旦bootloader成功启动,它将接管系统的控制权。
Bootloader启动后,负责从硬盘中找到内核文件,并将其加载到内存中执行,此时,操作系统正式开始运行。

操作系统的启动及进程管理:

操作系统启动后,会首先启动一个特殊的“老祖宗程序”,其进程ID(PID)为0。这个0号进程负责启动两个顶级进程:
  一个是init程序,其PID为1,负责管理用户态的进程。init程序是所有用户态进程的起点。
  另一个是kthreadd程序,其PID为2,负责管理内核态的进程。kthreadd是所有内核线程的起点。
  这些初始进程会进一步派生出其他进程,从而形成一棵进程树。用户态的进程(由1号进程衍生)负责执行用户级任务,而内核态的进程(由2号进程衍生)则处理系统级任务和硬件交互。

Linux系统的启动级别:

在Linux系统中,启动级别定义了系统启动后的不同运行模式,由init程序管理。常见的启动级别包括:
  0:关机模式
  6:重启模式
  3:字符终端模式(进入bash命令行环境)
  5:图形界面模式

通过这些启动级别,用户可以配置系统以满足不同的使用需求和环境。

 三、Shell解释器介绍

在Linux系统中,当init系统默认启动级别为3时,会自动启动一个名为命令解释器的应用程序。这类应用程序在Linux中统一被称为shell,即“壳”,这一称谓形象地诠释了其功能本质。shell实际上是对操作系统接口的进一步封装,将复杂的操作系统功能简化为一系列易于使用的命令,使用户能够更便捷地操控操作系统,而无需深入掌握底层技术。

POSIX标准:可移植操作系统接口(POSIX)为应用程序提供了一个统一的接口标准,旨在解决应用程序在不同操作系统上的兼容性问题,确保软件的可移植性。POSIX不仅传承了Unix API,还扩展至Linux、Windows等其他操作系统。通过遵循POSIX标准,操作系统间的差异得以最小化,使得应用程序能够在不同平台上无缝运行。这一标准涵盖了文件系统、程序接口、线程管理等多个方面,为应用程序的开发构筑了一个统一且可靠的平台。

四、shell 交互式环境详解

在交互式 shell 环境中,用户与系统之间进行实时对话。用户输入命令,系统执行该命令并立即将结果反馈给用户。这种即时响应的特性使得交互式环境非常适合逐条执行命令并进行测试。

在交互式环境中,你会看到一个提示符,它会不断闪烁,等待你的输入。提示符通常被中括号包围,里面包含了一些重要的信息,例如:[root@localhost ~]#。现在,我们来详细解释一下这些信息的含义:

root:表示当前登录的用户名。在这个例子中,显示的是 root 用户,意味着你以超级管理员的身份登录。

@:这是一个分隔符,用于将用户名和主机名分开。

localhost:表示主机的名称。这里显示的是 localhost,意味着你正在本机上工作。

~:这个符号表示你当前所在的文件夹。如果你看到的是 ~,那么它代表的是当前用户的家目录。对于 root 用户来说,家目录是 /root;对于普通用户来说,家目录是 /home/用户名。

#:这个符号表示当前登录的用户身份是超级管理员。只有在以 root 用户或其他具有超级管理员权限的用户身份登录时,你才会看到这个提示符。

$:这个符号表示当前登录的用户身份是一个普通用户。

image

image

现在,我们来看一下交互式和非交互式环境下用户添加和修改密码的方法:

交互式环境:
useradd 用户名:这条命令用于添加一个新用户。
passwd 用户名:这条命令会提示你输入新密码,用于为指定用户设置密码。

非交互式环境:
echo “密码” | passwd --stdin 用户名:这条命令可以在不交互的情况下为指定用户设置密码。它将密码通过管道传递给 passwd 命令,--stdin 选项告诉 passwd 命令从标准输入读取密码。

除了交互式命令执行,shell 还支持脚本编程。shell 脚本是一个包含一系列命令的文件,它可以自动执行一系列任务,而无需用户逐条输入命令。脚本文件可以包含任意多条命令,从而实现复杂的功能。这为系统管理和自动化任务提供了极大的便利。

总结来说,shell 交互式环境为用户提供了一个便捷的接口来与系统进行实时交互,而 shell 脚本则扩展了这种交互性,使得用户能够自动化执行复杂的任务。

五、Shell脚本

脚本犹如一个简易的程序,其简单程度甚至可以视作一个独立的文件。在交互式环境中输入命令具有实时反馈的特点,这使得单条命令的输入极为便捷。然而,我们亦可将多条Shell命令编排至一个文件中,以执行某项特定的任务,这类文件被称之为Shell脚本

Shell命令的基本语法如下

以“ls -l /boot”命令为例,其包含三大组成部分:
“ls”:此为命令本身,代表具体的操作指令。ls命令用于浏览指定文件夹下的子文件,或查看某个文件的信息。
“-l”:这是选项部分,用于控制命令的具体执行方式。若无选项,命令将按照默认行为执行,而添加选项后,命令的功能将更为丰富和灵活。
“/boot”:参数部分,指定命令操作的目标对象。

需补充的是,选项和参数均为可选部分,命令可以仅包含命令本身,如“ls”;可仅跟选项,如“ls -l”;亦可仅跟参数,如“ls /boot”

在Bash解释器的交互式环境中,还存在一些实用的特性和快捷方式:

“Ctrl+c”:用于强制终止当前命令的执行。
“Ctrl+l”:清屏功能,与“clear”命令效果相同。
“Ctrl+a”:将光标移至命令行的最前端。
“Ctrl+e”:将光标移至命令行的末尾。
“Ctrl+r”:搜索最近使用的历史命令。
“history”:查看之前执行过的命令列表,并可通过“!编号”重新执行特定命令。
“history -c”:清空历史命令记录。但实际操作中,由于我们通常通过远程工具连接服务器,清空目标主机的历史命令记录并无实质作用,因为跳转机仍会保留相关记录。
“Tab”:自动补全功能,可补全命令、参数等。

六、Shell命令的种类与优先级

Shell命令的种类繁多,且不同种类的命令之间存在优先级差异。如果两种Shell命令的名称相同,优先级较高的命令会覆盖较低优先级的命令。下面我们来详细了解一下Shell命令的种类及其优先级。

1)带路径的命令(绝对路径和相对路径)
Linux系统的目录结构是单根结构,所有路径的起始点都是根目录“/”,与Windows的多根目录结构不同。绝对路径从根目录开始,如“/a/b/c/1.txt”;而相对路径则是从当前目录开始,如“b/c/1.txt”。在相对路径中,“/”表示路径分隔符,“.”表示当前目录,“..”表示上一级目录。例如,“b/c/1.txt”等同于“./b/c/1.txt”,“/bin/ls”为绝对路径,而“./ls”则为相对路径,前提是必须处于“/bin”目录中。
(2)别名命令
别名命令通过“alias”命令创建,用于简化常用命令。例如,“alias xxx='ls /etc/sysconfig/network-scripts'”创建了一个名为“xxx”的别名,执行“xxx”时将等同于执行“ls /etc/sysconfig/network-scripts”。使用“unalias xxx”可以取消该别名。
(3)复合命令
复合命令在Shell编程中应用广泛,例如“for”循环和“if”判断语句都属于复合命令。虽然在bash中使用频率较低,但在脚本编写中会频繁用到。
(4)函数命令
通过“function”可以定义自定义命令或函数,实现特定功能。
(5)内置命令
内置命令是集成在Shell解释器中的命令,例如“cd”、“echo”等,优先级较高,因为它们直接由解释器处理。
(6)哈希缓存机制
为了提高命令执行效率,Shell会将执行过的命令缓存到内存中,下次直接使用缓存结果,避免查找和加载的开销。
(7)环境变量PATH
环境变量是一种存取内存的机制,PATH变量存储了一系列用于命令查找的目录,以冒号分隔。当Shell查找命令时,会按照PATH变量中指定的目录顺序进行搜索,确保在任何位置都能访问到命令。

总结命令的优先级如下:

带路径的命令优先级最高,因为它们直接指定了命令的位置。
如果没有带路径,Shell会首先查找是否有别名。
别名不存在时,查找复合命令。
再次查找是否存在同名的函数。
然后检查是否为内置命令。
如果以上都没有,Shell会检查哈希缓存中是否有该命令。
最后,Shell会在PATH变量指定的目录中查找命令。

通过理解这些命令种类及其优先级,我们可以更高效地使用Shell进行系统管理和脚本编程。

在Shell脚本中创建一条命令的步骤如下:

首先,编辑一个小脚本。使用vi命令,后面跟上要编辑的文件名,例如“vi mmm”。按下回车键后,你将进入vi编辑器内部。按下小写字母“a”键,当看到屏幕底部显示“INSERT”时,表示已经进入编辑模式,此时可以开始输入脚本内容。编辑完成后,按下“esc”键退出编辑模式,这时“INSERT”会消失。接着,输入“shift + 冒号”组合键,此时命令行处于等待输入指令的状态。“w”表示保存,“q”表示退出,而“wq”则表示保存并退出。完成这些操作后,脚本文件就编辑好了。

接下来,需要赋予这个脚本可执行权限。使用命令“chmod +x”,后面跟上脚本的路径,其中“+x”表示赋予可执行权限。要想无需前缀即可调用这个shell脚本,有两种方法:

方法一:将脚本移动到PATH环境变量中的某个文件夹下。
方法二:将脚本所在的文件夹添加到PATH环境变量中。

在Linux系统中,有几个基础且实用的命令对于日常操作至关重要。

首先是查看命令帮助信息的两种方法:使用'man'手册和'--help''-h'选项。
每当需要了解某个命令的详细用法时,可以通过'man'命令来访问其手册页。例如,输入'man ls',你将看到关于'ls'命令的详细介绍,包括它的用途、语法格式以及可选参数等。
而对于一些命令,你也可以在其后加上'--help''-h'来直接获取帮助信息,这种方式更为快捷,适合于需要快速了解基本用法的情况。
在系统管理方面,'hostname'命令用于查看当前主机的名称。如果需要更改主机名,可以使用'hostnamectl set-hostname'命令,例如,将主机名设置为'zrg':hostnamectl set-hostname zrg。这一更改会写入/etc/hostname文件中,并且是永久性的,重启后依然有效。
获取IP地址信息的命令是'ip a',它将显示所有活跃网卡的详细信息。若需要查看特定网卡的配置,比如'ens33',可以使用'ip a show ens33'。要激活网卡,可以使用'ifconfig ens33 up'或推荐使用的'nmcli conn up ens33'。
系统时间的查看和设置分别通过'date''date -s'命令完成。'date'命令会显示当前系统时间,而'date -s "2025-5-12 22:22:22"'则会将系统时间设置为指定的时间点。时间的显示格式也可以自定义,比如使用'date "+%F"''date "+%Y-%m-%d %H:%M:%S"'来按照特定格式显示。
对于系统的重启和关机,Linux提供了'shutdown'命令。'shutdown -r now'会立即重启系统,而'shutdown -h now'则立即关机。如果希望延迟执行,可以使用'shutdown -r 10'(10分钟后重启)或'shutdown -h 10'(10分钟后关机)。若要取消已计划的关机或重启操作,可以使用'shutdown -c'

 

posted @ 2025-09-07 01:59  张仁国  阅读(8)  评论(0)    收藏  举报
目录代码