Linux碎碎念

Linux发行版渊源

Linux是由Linus在1991年开始编写,其发行版本大体可以分为两类

  • 一类是商业公司维护的发行版本

    以Redhat为代表

  • 一类是社区组织维护的发行版本

    以Debian为代表

发行版分支

Red Hat 系操作系统

  • RHEL

    • 来源: Red Hat公司官方开发维护的企业级商业发行版
    • 包管理工具:
      • RHEL 7及以前: yum
      • RHEL 8及以后: dnf,底层为rpm包格式
  • CentOS

    • 来源: 基于RHEL源代码重新编译的二进制兼容社区版本
    • 包管理工具: 与对应版本的RHEL完全一致(CentOS 7用yum,CentOS 8用dnf)
  • openEuler (欧拉)

    • 来源: 华为贡献并开源的操作系统,与Fedora同源但自主演进
    • 包管理工具: dnf,兼容RHEL生态
  • Kylin (麒麟)

    • 来源: 早期版本基于Fedora(RPM系),新版V10已切换至Ubuntu Kylin (Debian系)
    • 包管理工具: yum/dnf
  • 鲲鹏 OS

    • 来源: 针对华为鲲鹏ARM处理器优化的版本
    • 包管理工具: 依据其基础发行版而定(openEuler用dnf,麒麟V10用apt)

Debian 系操作系统

  • Debian

    • 来源: 社区驱动的纯开源发行版,是众多Linux发行版的根基
    • 包管理工具: apt,底层为dpkg包格式
  • Ubuntu

    • 来源: 基于Debian的Unstable或Testing分支进行开发和完善
    • 包管理工具: apt ,deb包格式
  • Kylin (麒麟) V10 桌面版

    • 来源: 基于Ubuntu的官方衍生版本(Ubuntu Kylin)
    • 包管理工具: apt (与Ubuntu/Debian完全兼容)

两大发行版分支

依赖与编译

静态编译(Static Compilation):所有的库文件(例如,C语言的标准库)在编译时被直接链接到最终的可执行文件中。这样生成的可执行文件包含了所有需要的代码,因此可以在没有依赖库的情况下运行。

  • 优点:可执行文件是独立的,不依赖于外部库的版本,便于分发和运行。
  • 缺点:生成的可执行文件较大,更新库时需要重新编译程序。

动态编译(Dynamic Compilation):程序在运行时会动态链接到共享库(例如,系统的共享库)。这些共享库在系统中是独立存在的,程序只需要在运行时找到并使用它们。

  • 优点:可执行文件较小,多个程序可以共享同一个库,从而节省内存。
  • 缺点:如果共享库的版本发生变化,可能会导致程序不兼容的问题。

交叉编译(Cross Compilation):是指在一种平台(主机)上编译生成可在另一种平台(目标)上运行的程序的过程。它通常用于为不同架构(如x86、ARM等)编写软件时,开发环境和目标环境不相同的情况。

lib:是“library”的缩写,通常指的是库文件。库文件可以是静态库(以.a为后缀)或动态库(以.so为后缀)。
so:是“shared object”的缩写,指的是动态共享库,在Linux系统中通常以.so为后缀。动态库在运行时被加载,可以被多个程序共享。

glibc(GNU C Library):GNU项目的C标准库实现。它提供了C语言运行时所需的基本功能,包括系统调用、输入输出处理、字符串处理等。glibc是Linux系统上最常用的C库。

GNU项目:理查德·斯托曼于1983年发起的自由软件项目,旨在开发一个完全自由的类Unix操作系统。其中该羡慕包含多个组件,包括:

  • GNU汇编器集合(GCC):一个编译器框架,支持多种编程语言
  • GNU C Library (glibc):GNU项目的C标准库实现,为C程序提供基本的功能和系统调用接口。
  • GNU核心工具集(coreutils):基本的命令行工具,如lscpmv等。
  • GNU Bash:一种流行的命令行shell。

静态链接(Static Linking):静态链接是将所有需要的库和对象文件在编译时合并到一个可执行文件中。这样生成的可执行文件包含了运行所需的所有代码,运行时不需要查找外部库。

  • 相较于动态链接,静态链接的可执行文件较大且不易于维护。
  • 在没有库可用或者需要严格控制版本时(例如嵌入式系统),静态链接非常有用。

动态链接(Dynamic Linking):动态链接是指在程序运行时,将可执行文件与所需的动态链接库(共享库)连接起来。当一个程序启动时,操作系统会加载程序的代码和所依赖的共享库,而不是将所有的库代码直接包含到可执行文件中。

  • 共享代码:多个程序可以共享同一个动态库的代码,这样可以节省内存空间并减少可执行文件的大小。
  • 版本管理:使用动态链接时,可以独立更新共享库而无需重新编译依赖该库的程序,前提是新版本的库向后兼容。

glibc:是Linux系统中最常用的动态链接库之一,提供了C语言的标准库函数,例如字符串处理、数学运算、输入输出等功能,除了glibc,还有许多其他动态链接库。
libm.so:数学库,提供数学运算支持。
libpthread.so:POSIX线程库,支持多线程编程。
libdl.so:动态加载库,允许程序在运行时加载其他共享库。
libX11.so:X Window系统的库,为图形用户界面提供支持。

ldd 是一个用于显示一个可执行文件或共享库所需的共享库的命令行工具。它可以显示出程序在运行时会加载哪些动态链接库,以及这些库的路径。例如,可以使用以下命令来查看netstat可执行文件/共享库的依赖关系:

1
ldd /usr/bin/netstat

文件系统

https://www.zhihu.com/question/524667726/answer/2437952746

软链接、硬链接

服务管理

服务:Linux服务的本质是在后台持续运行的守护进程,通常在后台长期运行,伴随系统一起启停。

守护进程:守护进程是指在后台运行的程序,通常以d结尾,比如httpd(Apache HTTP服务器)和sshd(SSH服务守护进程)。

历史上管理服务的方式有三种,分别是initservicesystemctl

SysVinit

SysVinit是早期Linux系统的基础服务管理工具,在历史上,Linux的启动一直采用init进程。

传统的SysVinit系统使用启动脚本来启动和管理服务,它是计算机系统启动的第一个进程(守护进程),并持续运行,直到系统关闭。因此,它是所有其他进程的直接或间接的父进程

SysVinit中,所有的初始化脚本通常存放在/etc/init.d/目录下,它提供了两种主要方式来管理服务:****

  1. 直接使用init.d脚本
    使用init启动一个服务,可以使用以下命令:

    1
    $ sudo /etc/init.d/nginx start
  2. 通过service命令
    service命令是一个命令行工具,主要用于管理传统的SysVinit服务。它通过管理/etc/init.d目录下的脚本,实现服务的启动、停止、重启和状态查询。
    使用service启动一个服务:

    1
    $ service nginx start

    service命令实际上是对/etc/init.d/目录下脚本的封装,提供了更统一的接口

基于SysVinit模式的服务管理存在以下缺点:

  1. 启动时间长init进程是串行启动的,只有前一个进程启动完,才能启动下一个进程。
  2. 启动脚本复杂init进程只是执行启动脚本,不处理其他情况,脚本需要自行处理各种状况,这往往使得脚本变得很长且复杂。
  3. 依赖管理不足:服务之间的依赖关系需要手动配置,容易出错且难以维护。

Systemd

Systemd就是为了解决上述的问题而诞生的,它是现代Linux系统中取代SysVinit的服务管理工具。它通过并行启动服务来显著提高系统启动速度,并且提供了一套完整的服务管理框架。

根据 Linux 惯例,字母d是守护进程(daemon)的缩写。Systemd 这个名字的含义,就是它要守护整个系统。

使用了 Systemd,就不需要再用init 了。Systemd 取代了initd(Initd 的PID 是0) ,成为系统的第一个进程(Systemd 的PID 等于 1),其他进程都是它的子进程。

Systemd的服务管理

Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面,它有:systemctlhostnamectllocalectltimedatectl

systemctl是 Systemd 的主命令,用于管理系统。

1
2
3
4
5
6
7
8
// 重启系统
$ sudo systemctl reboot

// 启动进入救援状态(单用户状态)
$ sudo systemctl rescue

// 管理服务
$ sudo systemctl start nginx

Systemd的单元文件

Systemd中,服务的配置文件通常位于/etc/systemd/system//lib/systemd/system/目录下,可以通过向/etc/systemd/system/目录写入.service文件来实现自定义服务,并使用systemctl进行控制。

一个典型的服务单元文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=NGINX Web Server
After=network.target

[Service]
ExecStart=/usr/sbin/nginx -g "daemon off;"
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=process
Restart=always

[Install]
WantedBy=multi-user.target

单元文件分为三个主要部分:

  • [Unit]:定义单元的元数据和与其他单元的关系
    Description:进行服务简要说明
    After、Requires:指定服务的依赖关系和启动顺序等
  • [Service]:服务特有的配置(启动命令、重启策略等)
    Type:定义服务类型
    ExecStart:指定启动的程序路径/执行的命令
    SuccessExitStatus:表示当服务进程的退出状态码
  • [Install]:定义如何安装此单元(如开机启动)
    WantedBy:指定服务所属的target目标单元(如multi-user.target在多用户模式下启动,graphical.target表示图形界面模式)

SysVinit相比,Systemd具有以下优点:

  1. 并行启动Systemd可以并行启动服务,大大缩短启动时间。
  2. 依赖管理Systemd能够自动管理服务之间的依赖关系,确保按需启动。
  3. 简单的配置Systemd使用单位(unit)文件来配置服务,简化了管理和配置的复杂性。
  4. 状态管理Systemd提供更为丰富的状态管理和日志记录功能,例如使用journalctl查看服务日志。

总结

  • init 是最初的进程管理方式
  • serviceinit 的另一种实现
  • systemd 则是一种取代 initd 的解决方案
功能 SysVinit systemd
启动方式 串行启动 并行启动
管理方式 init.d脚本 systemctl命令
依赖管理 手动配置 自动处理
启动速度
日志管理 /var/log/messages journalctl
是否支持cgroups
默认运行级别 0-6 多目标(target)替代
服务状态查询 service命令 systemctl status

其中 systemctlsystemd 的主命令,用于管理系统以及服务。

.d

我们有时会发现部分文件存在着以.d结尾的另一份文件或目录,它们对应的含义其实为:

  1. dependence - 依赖,即依赖文件

  2. default - 默认,即默认配置文件

    例如/etc下很多携带.d的文件夹,表示文件夹下有系统缺省的配置文件

  3. dynamic - 动态,动态意义的文件

iptables

iptables-save

iptables -I INPUT -s 10.0.0.0/16 -j ACCEPT

Root越权

setuid

实用工具

这里记录一些非常实用的快捷键:

Ctrl + R反向搜索:非常推荐使用,可以快速查找之前执行过的命令,按下多次Ctrl + R向下继续查找。

  • 如果已经在使用 Ctrl + R 进行反向搜索,可以按 Ctrl + S 进行正向搜索(需要在某些终端中启用)

tmux

tmux(terminal multiplexer)是一个终端复用器,允许我们在一个单一的终端窗口中运行多个会话。

基本命令与快捷键:

  • 启动 tmux:tmux
  • 创建一个新会话:tmux new -s session_name
  • 列出会话:tmux list-sessionstmux ls
  • 连接到一个会话:tmux attach -t session_nametmux a -t session_name
  • 分离会话:按下 Ctrl + b 然后按下 d
  • 创建新窗口:按下 Ctrl + b 然后按下 c
  • 垂直分屏:按下 Ctrl + b 然后按下 |
  • 水平分屏:按下 Ctrl + b 然后按下 %
  • 切换窗口:按下 Ctrl + b 然后按下窗口编号
  • 复制模式:按下 Ctrl + b 然后按下 [

vim

撤回和重做

  • 撤回u (撤销上一个操作)
  • 重做Ctrl + r (重做上一个撤销的操作)

替换和删除

  • 替换当前光标单词ciw (改变整个单词,进入插入模式)
  • 删除当前光标单词diw (删除整个单词,不进入插入模式)
  • 删除当前光标后面的字符:x (删除光标所在位置的字符)
  • 删除当前行dd (删除光标所在的整行)

复制和粘贴

  • 复制当前行yy (“yank” 当前行)
  • 粘贴p (在光标后粘贴已复制的文本)
  • 复制选定文本:v 进入可视模式,选择文本后按 y (yank 选定文本)

插入和切换模式

  • 进入插入模式:i (在光标前插入)
  • 在光标后插入a (在光标后插入)
  • 退出插入模式:Esc
  • 进入命令模式:: (在命令行输入命令)

查找和替换

  • 向上查找文本?要查找的文本 (向上↑查)
  • 向下查找文本/要查找的文本 (向下↓查)
  • 查找下一个n (查找下一个匹配)
  • 查找上一个N (查找上一个匹配)
  • 替换文本:s/旧文本/新文本/g (在当前行替换)
  • 全局替换: %s/旧文本/新文本/g (在整个文件中替换)

文本操作

  • 移动光标到文件开头gg
  • 移动光标到文件结尾G
  • 跳转到当前行的第一个字符:0
  • 跳转到当前行的最后一个字符:$

缩进和格式化

  • 增加缩进:> (在可视模式下选择文本后使用)
  • 减少缩进:< (在可视模式下选择文本后使用)
  • 格式化当前段落:gqap (格式化光标所在段落)

find

根据文件名、类型、大小、修改时间等搜索文件和目录

基本语法:find [路径] [选项] [条件]

名称查找find /etc -name "filename.txt"

  • 可以用*代表正则中的匹配所有字符
  • -iname忽略大小写
  • -type f查找文件、-type d查找目录
  • -size +100M查找大于 100MB 的文件,-100M同理
  • -mtime -7查找在过去 7 天内被修改过的文件
  • -exec rm {} \\;对找到的每个文件执行指定的命令,这里是删除
  • -empty查找空文件
  • -maxdepth 1设置最大查找深度
  • -mindepth 1设置最小查找深度

Linux碎碎念
https://www.fishingrodd.cn/2025/07/27/Linux碎碎念/
作者
FishingRod
发布于
2025年7月27日
更新于
2025年8月24日
许可协议