Linux 系统编程 · 第 1 章:Linux 系统概述
2026/6/12 16:41:15 网站建设 项目流程

Linux 系统编程 · 第 1 章:Linux 系统概述

本章涵盖 Linux 内核、Shell 与文件系统三大核心主题,配合代码示例深入理解底层机制。


目录

  1. Linux 内核(Kernel)

  2. Shell

  3. 文件系统结构


1. Linux 内核(Kernel)

1.1 内核概述

Linux 内核是操作系统的核心,运行在内核态(Kernel Space),负责管理硬件资源并向上层提供系统调用接口。

┌─────────────────────────────────────────┐ │ 用户应用程序 (User Space) │ │ Shell / Python / C程序 / 浏览器 ... │ ├─────────────────────────────────────────┤ │ 系统调用接口 (System Call API) │ ← 用户态 / 内核态 边界 ├─────────────────────────────────────────┤ │ Linux 内核 (Kernel) │ │ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │ │ 进程管理 │ │ 内存管理 │ │文件系统 │ │ │ └──────────┘ └──────────┘ └─────────┘ │ │ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │ │ 网络子系统│ │ 设备驱动 │ │安全模块 │ │ │ └──────────┘ └──────────┘ └─────────┘ │ ├─────────────────────────────────────────┤ │ 硬件 (Hardware) │ │ CPU / 内存 / 磁盘 / 网卡 ... │ └─────────────────────────────────────────┘

1.2 内核的主要功能模块

模块职责
进程管理进程创建、调度、销毁、进程间通信(IPC)
内存管理虚拟内存、分页、内存分配与回收
文件系统VFS 抽象层、ext4/xfs/tmpfs 等具体实现
网络子系统TCP/IP 协议栈、套接字接口
设备驱动字符设备、块设备、网络设备驱动
安全模块SELinux、AppArmor、Capabilities

1.3 用户态与内核态

程序运行在两种特权级别:

  • 用户态(User Mode):受限访问,不能直接操作硬件

  • 内核态(Kernel Mode):完全访问权限,可操作所有硬件资源

用户程序通过系统调用(syscall)陷入内核态执行特权操作。

/* 示例:通过系统调用写入数据 * write() 是 C 库封装,底层触发 sys_write 系统调用 * 执行流程:用户态 → 软中断/syscall指令 → 内核态 → 返回用户态 */ #include <unistd.h> #include <stdio.h> ​ int main(void) { const char *msg = "Hello, Linux Kernel!\n"; ​ /* write(fd, buf, count) * fd=1 表示标准输出(STDOUT_FILENO) * 返回实际写入的字节数,-1 表示出错 */ ssize_t n = write(STDOUT_FILENO, msg, 21); if (n == -1) { perror("write"); /* perror 打印 errno 对应的错误信息 */ return 1; } printf("写入了 %zd 字节\n", n); return 0; }

编译与运行:

gcc -o hello_kernel hello_kernel.c ./hello_kernel # 输出: # Hello, Linux Kernel! # 写入了 21 字节

使用strace追踪系统调用:

strace ./hello_kernel 2>&1 | grep write # 输出类似: # write(1, "Hello, Linux Kernel!\n", 21) = 21

💡strace是调试利器,可以看到程序实际触发了哪些系统调用及其参数和返回值。


1.4 查看内核信息

# 查看内核版本 uname -r # 示例输出:5.15.0-91-generic ​ # 查看完整系统信息 uname -a # 示例输出:Linux hostname 5.15.0-91-generic #101-Ubuntu SMP x86_64 GNU/Linux ​ # 查看内核启动日志(需要权限) dmesg | head -20 ​ # 查看 /proc 虚拟文件系统中的内核信息 cat /proc/version # 内核版本 cat /proc/cpuinfo # CPU 信息 cat /proc/meminfo # 内存信息 cat /proc/sys/kernel/pid_max # 最大 PID 数

1.5 系统调用机制详解

/* 直接使用 syscall() 函数调用系统调用(绕过 C 库封装) * 用于理解底层机制,实际开发中使用 C 库封装函数 */ #include <sys/syscall.h> #include <unistd.h> #include <stdio.h> ​ int main(void) { /* SYS_getpid 是系统调用号,对应内核中的 sys_getpid() * 在 x86_64 上,getpid 的系统调用号为 39 */ pid_t pid = (pid_t)syscall(SYS_getpid); printf("当前进程 PID(通过 syscall): %d\n", pid); ​ /* 对比:使用 C 库封装的 getpid() */ printf("当前进程 PID(通过 libc): %d\n", getpid()); ​ /* 两者结果相同,但 libc 版本有缓存优化 */ return 0; }
gcc -o syscall_demo syscall_demo.c ./syscall_demo # 输出: # 当前进程 PID(通过 syscall): 12345 # 当前进程 PID(通过 libc): 12345

2. Shell

2.1 Shell 概述

Shell 是用户与内核之间的命令解释器,既是交互式命令行工具,也是脚本编程语言。

用户输入命令 │ ▼ ┌─────────────┐ │ Shell │ ← 解析命令、展开变量、处理重定向 │ (bash/zsh) │ └──────┬──────┘ │ fork() + exec() ▼ ┌─────────────┐ │ 子进程执行 │ ← 实际运行 ls、grep、python 等程序 │ 外部命令 │ └──────┬──────┘ │ wait() 等待子进程 ▼ 返回结果给用户

2.2 常见 Shell 类型

Shell路径特点
bash/bin/bash最常用,兼容 POSIX,功能丰富
sh/bin/shPOSIX 标准 Shell,轻量
zsh/bin/zsh功能强大,macOS 默认
dash/bin/dash极轻量,Ubuntu 默认/bin/sh
fish/usr/bin/fish用户友好,语法不兼容 POSIX
# 查看当前使用的 Shell echo $SHELL # 登录 Shell echo $0 # 当前 Shell 进程名 # 查看系统中所有可用 Shell cat /etc/shells # 查看 bash 版本 bash --version

2.3 Shell 变量与环境变量

#!/bin/bash # 文件名:variables_demo.sh # ── 1. 普通变量(局部于当前 Shell)────────────────────── name="Linux" version=5.15 echo "系统: $name, 内核版本: $version" # 注意:= 两侧不能有空格! # name = "Linux" ← 错误写法 # ── 2. 只读变量 ────────────────────────────────────────── readonly MAX_RETRY=3 echo "最大重试次数: $MAX_RETRY" # MAX_RETRY=5 ← 会报错:readonly variable # ── 3. 环境变量(可被子进程继承)──────────────────────── export APP_ENV="production" export DB_HOST="localhost" # 验证子进程能否看到环境变量 bash -c 'echo "子进程看到 APP_ENV=$APP_ENV"' # ── 4. 特殊变量 ────────────────────────────────────────── echo "脚本名称: $0" echo "第一个参数: $1" echo "参数个数: $#" echo "所有参数: $@" echo "上条命令退出码: $?" echo "当前进程 PID: $$" echo "后台最后进程PID: $!"
chmod +x variables_demo.sh ./variables_demo.sh arg1 arg2

2.4 Shell 控制流

#!/bin/bash # 文件名:control_flow.sh # ── 1. 条件判断 ────────────────────────────────────────── FILE="/etc/passwd" if [ -f "$FILE" ]; then echo "$FILE 存在且是普通文件" elif [ -d "$FILE" ]; then echo "$FILE 是目录" else echo "$FILE 不存在" fi # 常用文件测试操作符: # -f 普通文件 -d 目录 -e 存在 # -r 可读 -w 可写 -x 可执行 # -s 非空文件 -L 符号链接 # ── 2. 字符串比较 ───────────────────────────────────────── OS=$(uname -s) case "$OS" in Linux) echo "运行在 Linux 系统上" ;; Darwin) echo "运行在 macOS 系统上" ;; *) echo "未知系统: $OS" ;; esac # ── 3. 循环 ─────────────────────────────────────────────── echo "--- for 循环遍历 /etc 下的配置文件 ---" for conf in /etc/*.conf; do # basename 去掉路径,只保留文件名 echo " 配置文件: $(basename "$conf")" done echo "--- while 循环读取文件内容 ---" line_num=1 while IFS= read -r line; do echo " 第${line_num}行: $line" ((line_num++)) [ $line_num -gt 3 ] && break # 只读前3行 done < /etc/os-release

2.5 Shell 函数与错误处理

#!/bin/bash # 文件名:functions_demo.sh # ── 严格模式(推荐在脚本开头加上)──────────────────────── set -euo pipefail # -e 遇到错误立即退出 # -u 使用未定义变量时报错 # -o pipefail 管道中任一命令失败则整体失败 # ── 函数定义 ────────────────────────────────────────────── # 检查命令是否存在 check_command() { local cmd="$1" # local 声明局部变量,避免污染全局 if command -v "$cmd" &>/dev/null; then echo "✓ $cmd 已安装: $(command -v "$cmd")" return 0 # 返回值 0 表示成功 else echo "✗ $cmd 未安装" return 1 # 非零返回值表示失败 fi } # 获取文件大小(带单位) get_file_size() { local file="$1" if [ ! -f "$file" ]; then echo "错误: 文件不存在 '$file'" >&2 # 错误信息输出到 stderr return 1 fi # du -sh 以人类可读格式显示大小 du -sh "$file" | awk '{print $1}' } # ── 调用函数 ────────────────────────────────────────────── check_command "bash" check_command "python3" check_command "nonexistent_tool" || echo "(上面的错误是预期的)" size=$(get_file_size "/etc/passwd") echo "/etc/passwd 大小: $size" # ── 陷阱(trap):捕获信号和退出事件 ───────────────────── cleanup() { echo "脚本退出,执行清理操作..." # 删除临时文件等清理工作 } trap cleanup EXIT # 脚本退出时执行 cleanup trap 'echo "收到 Ctrl+C"' INT # 捕获 SIGINT 信号

2.6 管道与重定向

# ── 重定向 ──────────────────────────────────────────────── # 标准输入(0)、标准输出(1)、标准错误(2) # 输出重定向(覆盖) echo "Hello" > output.txt # 输出重定向(追加) echo "World" >> output.txt # 错误重定向 ls /nonexistent 2> error.log # 同时重定向 stdout 和 stderr 到同一文件 ls /etc /nonexistent > all.log 2>&1 # 丢弃输出(/dev/null 是"黑洞") command_with_noise > /dev/null 2>&1 # 输入重定向 sort < unsorted.txt > sorted.txt # Here Document(内嵌多行文本) cat << 'EOF' > config.txt HOST=localhost PORT=8080 DEBUG=false EOF # ── 管道(pipe)───────────────────────────────────────── # 将前一个命令的 stdout 连接到后一个命令的 stdin # 统计 /etc 目录下文件数量 ls /etc | wc -l # 查找占用内存最多的前5个进程 ps aux --sort=-%mem | head -6 # 实时监控日志中的错误 tail -f /var/log/syslog | grep --line-buffered "ERROR" # 复杂管道:统计 /etc 下各类型文件数量 find /etc -maxdepth 1 -type f -name "*.conf" 2>/dev/null \ | xargs wc -l 2>/dev/null \ | sort -rn \ | head -10

3. 文件系统结构

3.1 FHS 目录层次标准

Linux 遵循FHS(Filesystem Hierarchy Standard,文件系统层次标准),所有文件从根目录/开始组织。

/ ← 根目录(所有文件的起点) ├── bin → /usr/bin ← 基本用户命令(ls, cp, mv...) ├── sbin → /usr/sbin ← 系统管理命令(fdisk, ifconfig...) ├── boot ← 启动文件(内核镜像、GRUB) │ ├── vmlinuz-5.15.0 ← 压缩的内核镜像 │ └── grub/ ← GRUB 引导程序配置 ├── dev ← 设备文件(字符/块设备) │ ├── sda ← 第一块 SATA 硬盘 │ ├── tty0 ← 终端设备 │ ├── null ← 空设备(黑洞) │ └── random ← 随机数生成器 ├── etc ← 系统配置文件 │ ├── passwd ← 用户账户信息 │ ├── fstab ← 文件系统挂载表 │ └── hosts ← 主机名解析 ├── home ← 普通用户主目录 │ └── alice/ ← 用户 alice 的家目录 ├── lib → /usr/lib ← 共享库文件(.so) ├── media ← 可移动媒体挂载点(U盘、光盘) ├── mnt ← 临时挂载点 ├── opt ← 第三方软件安装目录 ├── proc ← 进程和内核信息虚拟文件系统 │ ├── 1/ ← PID=1 的进程信息(init/systemd) │ ├── cpuinfo ← CPU 信息 │ └── meminfo ← 内存信息 ├── root ← root 用户的主目录 ├── run ← 运行时数据(PID文件、套接字) ├── srv ← 服务数据(Web、FTP) ├── sys ← 内核设备树虚拟文件系统(sysfs) ├── tmp ← 临时文件(重启后清空) ├── usr ← 用户程序和数据 │ ├── bin/ ← 用户命令 │ ├── include/ ← C/C++ 头文件 │ ├── lib/ ← 库文件 │ └── share/ ← 架构无关数据 └── var ← 可变数据 ├── log/ ← 日志文件 ├── spool/ ← 打印队列、邮件队列 └── tmp/ ← 持久临时文件

3.2 重要目录详解

/proc— 进程与内核信息虚拟文件系统

/proc不是真实的磁盘文件系统,而是内核在内存中动态生成的虚拟文件系统

# 查看当前进程信息 PID=$$ # 当前 Shell 的 PID echo "当前 Shell PID: $PID" ls /proc/$PID/ # 输出:cmdline cwd environ exe fd maps mem stat status ... # 查看进程命令行 cat /proc/$PID/cmdline | tr '\0' ' ' # 查看进程内存映射 cat /proc/$PID/maps | head -10 # 查看进程打开的文件描述符 ls -la /proc/$PID/fd # 查看进程状态 cat /proc/$PID/status | grep -E "Name|Pid|VmRSS|Threads"
/* 用 C 程序读取 /proc/meminfo 获取内存信息 */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { FILE *fp = fopen("/proc/meminfo", "r"); if (!fp) { perror("fopen /proc/meminfo"); return 1; } char line[256]; int count = 0; printf("=== 内存信息 ===\n"); while (fgets(line, sizeof(line), fp) && count < 5) { /* 只打印前5行关键信息 */ printf("%s", line); count++; } fclose(fp); return 0; }
gcc -o read_meminfo read_meminfo.c ./read_meminfo # 输出示例: # === 内存信息 === # MemTotal: 16384000 kB # MemFree: 8192000 kB # MemAvailable: 10240000 kB # Buffers: 512000 kB # Cached: 2048000 kB

/dev— 设备文件

Linux 中"一切皆文件",硬件设备也以文件形式存在于/dev

# 查看块设备 lsblk ls -la /dev/sd* # SATA/SCSI 磁盘 ls -la /dev/nvme* # NVMe 固态硬盘 # 特殊设备 # /dev/null - 丢弃所有写入,读取返回 EOF # /dev/zero - 读取返回无限的 0 字节 # /dev/random - 阻塞式随机数(熵池) # /dev/urandom - 非阻塞随机数 # 用 /dev/zero 创建指定大小的空文件 dd if=/dev/zero of=test_1MB.bin bs=1M count=1 ls -lh test_1MB.bin # 输出:-rw-r--r-- 1 user group 1.0M ... # 生成随机密码(16字节,base64编码) dd if=/dev/urandom bs=16 count=1 2>/dev/null | base64
/* 演示设备文件的读写操作 */ #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(void) { unsigned char buf[16]; int fd; /* 从 /dev/urandom 读取随机字节 */ fd = open("/dev/urandom", O_RDONLY); if (fd == -1) { perror("open /dev/urandom"); return 1; } ssize_t n = read(fd, buf, sizeof(buf)); close(fd); if (n != sizeof(buf)) { fprintf(stderr, "读取不完整\n"); return 1; } printf("随机字节(十六进制): "); for (int i = 0; i < (int)n; i++) { printf("%02x ", buf[i]); } printf("\n"); return 0; }

3.3 文件类型

Linux 有 7 种文件类型,用ls -l第一个字符标识:

标识符类型说明
-普通文件文本、二进制、可执行文件
d目录包含其他文件的容器
l符号链接指向另一个文件的快捷方式
c字符设备按字节流访问(终端、串口)
b块设备按块访问(硬盘、U盘)
p命名管道FIFO,进程间通信
s套接字网络/本地进程间通信
# 查看各种文件类型示例 ls -la /dev/null # c --- 字符设备 ls -la /dev/sda # b --- 块设备(如果存在) ls -la /bin # l --- 符号链接(指向 /usr/bin) ls -la /tmp # d --- 目录 ls -la /etc/passwd # - --- 普通文件 # 用 file 命令识别文件类型(不依赖扩展名) file /bin/bash # ELF 64-bit LSB pie executable file /etc/passwd # ASCII text file /usr/lib/x86_64-linux-gnu/libc.so.6 # ELF shared object
/* 使用 stat() 系统调用获取文件元数据 */ #include <stdio.h> #include <sys/stat.h> #include <time.h> /* 根据 st_mode 返回文件类型字符串 */ const char *file_type(mode_t mode) { if (S_ISREG(mode)) return "普通文件"; if (S_ISDIR(mode)) return "目录"; if (S_ISLNK(mode)) return "符号链接"; if (S_ISCHR(mode)) return "字符设备"; if (S_ISBLK(mode)) return "块设备"; if (S_ISFIFO(mode)) return "命名管道"; if (S_ISSOCK(mode)) return "套接字"; return "未知类型"; } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "用法: %s <文件路径>\n", argv[0]); return 1; } struct stat st; /* lstat 不跟随符号链接,stat 会跟随 */ if (lstat(argv[1], &st) == -1) { perror("lstat"); return 1; } printf("文件路径: %s\n", argv[1]); printf("文件类型: %s\n", file_type(st.st_mode)); printf("文件大小: %ld 字节\n", (long)st.st_size); printf("硬链接数: %lu\n", (unsigned long)st.st_nlink); printf("所有者 UID: %u\n", st.st_uid); printf("所属组 GID: %u\n", st.st_gid); printf("inode 号: %lu\n", (unsigned long)st.st_ino); /* 格式化时间 */ char timebuf[64]; struct tm *tm_info = localtime(&st.st_mtime); strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm_info); printf("修改时间: %s\n", timebuf); /* 打印权限位(rwxrwxrwx 格式) */ printf("权限: %c%c%c%c%c%c%c%c%c\n", (st.st_mode & S_IRUSR) ? 'r' : '-', (st.st_mode & S_IWUSR) ? 'w' : '-', (st.st_mode & S_IXUSR) ? 'x' : '-', (st.st_mode & S_IRGRP) ? 'r' : '-', (st.st_mode & S_IWGRP) ? 'w' : '-', (st.st_mode & S_IXGRP) ? 'x' : '-', (st.st_mode & S_IROTH) ? 'r' : '-', (st.st_mode & S_IWOTH) ? 'w' : '-', (st.st_mode & S_IXOTH) ? 'x' : '-'); return 0; }
gcc -o file_info file_info.c ./file_info /etc/passwd # 输出示例: # 文件路径: /etc/passwd # 文件类型: 普通文件 # 文件大小: 2847 字节 # 硬链接数: 1 # 所有者 UID: 0 # 所属组 GID: 0 # inode 号: 131073 # 修改时间: 2024-01-15 10:30:00 # 权限: rw-r--r--

3.4 文件权限与 inode

权限模型
权限字符串示例:-rwxr-xr-- │││││││││└── 其他用户:只读 ││││││└──── 所属组:读+执行 │││└─────── 所有者:读+写+执行 └────────── 文件类型:- 普通文件 数字表示: r = 4, w = 2, x = 1 rwxr-xr-- = 754
# 修改权限 chmod 755 script.sh # 数字方式 chmod u+x,g-w,o-x file.txt # 符号方式 # 修改所有者 chown alice:developers file.txt # 查看权限(详细) stat /etc/passwd ls -l /etc/passwd # umask:新建文件的默认权限掩码 umask # 查看当前 umask(通常是 022) umask 027 # 设置 umask(新文件权限 = 666 & ~027 = 640)
inode 机制
/* 演示硬链接与 inode 的关系 */ #include <stdio.h> #include <sys/stat.h> #include <unistd.h> int main(void) { /* 创建一个文件 */ FILE *fp = fopen("original.txt", "w"); fprintf(fp, "Hello, inode!\n"); fclose(fp); /* 创建硬链接(两个文件名指向同一个 inode) */ if (link("original.txt", "hardlink.txt") == -1) { perror("link"); return 1; } /* 创建软链接(符号链接,存储路径字符串) */ if (symlink("original.txt", "softlink.txt") == -1) { perror("symlink"); return 1; } /* 比较三个文件的 inode 号 */ struct stat st1, st2, st3; stat("original.txt", &st1); stat("hardlink.txt", &st2); lstat("softlink.txt", &st3); /* lstat 不跟随符号链接 */ printf("original.txt inode: %lu, 硬链接数: %lu\n", (unsigned long)st1.st_ino, (unsigned long)st1.st_nlink); printf("hardlink.txt inode: %lu, 硬链接数: %lu\n", (unsigned long)st2.st_ino, (unsigned long)st2.st_nlink); printf("softlink.txt inode: %lu (符号链接自身)\n", (unsigned long)st3.st_ino); printf("\n硬链接与原文件 inode 相同: %s\n", st1.st_ino == st2.st_ino ? "是 ✓" : "否 ✗"); printf("软链接与原文件 inode 相同: %s\n", st1.st_ino == st3.st_ino ? "是" : "否 ✓(符号链接有自己的inode)"); /* 清理 */ unlink("original.txt"); unlink("hardlink.txt"); unlink("softlink.txt"); return 0; }
gcc -o inode_demo inode_demo.c ./inode_demo # 输出示例: # original.txt inode: 1234567, 硬链接数: 2 # hardlink.txt inode: 1234567, 硬链接数: 2 # softlink.txt inode: 1234568 (符号链接自身) # # 硬链接与原文件 inode 相同: 是 ✓ # 软链接与原文件 inode 相同: 否 ✓(符号链接有自己的inode)

3.5 文件系统挂载

# 查看当前挂载的文件系统 mount | column -t # 或 df -hT # 显示磁盘使用情况和文件系统类型 # 挂载 U 盘(需要 root 权限) # mount /dev/sdb1 /mnt/usb # 查看 /etc/fstab(开机自动挂载配置) cat /etc/fstab # 格式:设备 挂载点 文件系统类型 选项 dump pass # 查看支持的文件系统类型 cat /proc/filesystems
/* 使用 statvfs() 获取文件系统统计信息 */ #include <stdio.h> #include <sys/statvfs.h> int main(int argc, char *argv[]) { const char *path = (argc > 1) ? argv[1] : "/"; struct statvfs vfs; if (statvfs(path, &vfs) == -1) { perror("statvfs"); return 1; } unsigned long long total = (unsigned long long)vfs.f_blocks * vfs.f_frsize; unsigned long long free = (unsigned long long)vfs.f_bfree * vfs.f_frsize; unsigned long long avail = (unsigned long long)vfs.f_bavail * vfs.f_frsize; unsigned long long used = total - free; printf("文件系统路径: %s\n", path); printf("块大小: %lu 字节\n", vfs.f_bsize); printf("总空间: %.2f GB\n", total / 1e9); printf("已用空间: %.2f GB\n", used / 1e9); printf("可用空间: %.2f GB\n", avail / 1e9); printf("使用率: %.1f%%\n", (double)used / total * 100); printf("总 inode 数: %lu\n", (unsigned long)vfs.f_files); printf("空闲 inode 数: %lu\n", (unsigned long)vfs.f_ffree); return 0; }
gcc -o fs_info fs_info.c ./fs_info / # 输出示例: # 文件系统路径: / # 块大小: 4096 字节 # 总空间: 107.37 GB # 已用空间: 23.45 GB # 可用空间: 78.56 GB # 使用率: 21.8% # 总 inode 数: 6553600 # 空闲 inode 数: 6123456

综合实践:系统信息汇总脚本

#!/bin/bash # 文件名:sysinfo.sh # 功能:综合展示内核、Shell、文件系统信息 set -euo pipefail # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color print_section() { echo -e "\n${BLUE}══════════════════════════════════════${NC}" echo -e "${GREEN} $1${NC}" echo -e "${BLUE}══════════════════════════════════════${NC}" } # ── 1. 内核信息 ─────────────────────────────────────────── print_section "🐧 内核信息" echo "内核版本: $(uname -r)" echo "系统架构: $(uname -m)" echo "主机名: $(hostname)" echo "系统启动时间: $(uptime -s 2>/dev/null || uptime | awk '{print $3,$4}' | tr -d ',')" # ── 2. Shell 信息 ───────────────────────────────────────── print_section "🐚 Shell 信息" echo "当前 Shell: $SHELL" echo "Shell 版本: $($SHELL --version 2>&1 | head -1)" echo "当前 PID: $$" echo "登录用户: $(whoami)" # ── 3. 内存信息(读取 /proc/meminfo)──────────────────── print_section "💾 内存信息" awk '/^MemTotal|^MemFree|^MemAvailable|^SwapTotal|^SwapFree/ { printf "%-20s %8.1f MB\n", $1, $2/1024 }' /proc/meminfo # ── 4. 文件系统信息 ─────────────────────────────────────── print_section "📁 文件系统使用情况" df -hT | grep -v "tmpfs\|devtmpfs\|udev" | \ awk 'NR==1{print} NR>1{ # 根据使用率着色 use=$6; gsub(/%/,"",use) if(use+0 > 80) color="\033[0;31m" else if(use+0 > 60) color="\033[1;33m" else color="\033[0;32m" printf "%s%s\033[0m\n", color, $0 }' # ── 5. 重要目录大小 ─────────────────────────────────────── print_section "📊 重要目录大小" for dir in /etc /var/log /tmp /home; do if [ -d "$dir" ]; then size=$(du -sh "$dir" 2>/dev/null | awk '{print $1}') printf " %-15s %s\n" "$dir" "$size" fi done # ── 6. 进程统计 ─────────────────────────────────────────── print_section "⚙️ 进程统计" echo "总进程数: $(ps aux | wc -l)" echo "运行中进程: $(ps aux | awk '$8~/^R/{count++} END{print count+0}')" echo "CPU 核心数: $(nproc)" echo "系统负载: $(cat /proc/loadavg | awk '{print $1,$2,$3}')" echo -e "\n${GREEN}✓ 系统信息汇总完成${NC}\n"
chmod +x sysinfo.sh ./sysinfo.sh

知识点总结

Linux 系统编程第1章 核心知识图谱 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┌─────────────────────────────────────────────────────────┐ │ Linux 系统概述 │ └──────────────┬──────────────────┬───────────────────────┘ │ │ │ ┌──────▼──────┐ ┌───────▼──────┐ ┌──────▼──────┐ │ 内核 │ │ Shell │ │ 文件系统 │ │ Kernel │ │ │ │ Structure │ └──────┬──────┘ └───────┬──────┘ └──────┬──────┘ │ │ │ ┌──────▼──────┐ ┌───────▼──────┐ ┌──────▼──────┐ │ • 进程管理 │ │ • 变量/环境 │ │ • FHS 标准 │ │ • 内存管理 │ │ • 控制流 │ │ • /proc虚拟 │ │ • 设备驱动 │ │ • 函数/陷阱 │ │ • /dev设备 │ │ • 系统调用 │ │ • 管道/重定向│ │ • inode机制 │ │ • 用户/内核态│ │ • 错误处理 │ │ • 文件类型 │ └─────────────┘ └─────────────┘ └─────────────┘ 关键系统调用:write() read() open() close() stat() lstat() getpid() fork() exec() link() symlink() 关键虚拟文件:/proc/meminfo /proc/cpuinfo /proc/[pid]/ /proc/filesystems /proc/loadavg ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📚参考资料

  • 《Linux/UNIX 系统编程手册》— Michael Kerrisk

  • 《深入理解 Linux 内核》— Daniel P. Bovet

  • Linux man pages:man 2 syscall,man 7 hier,man 5 proc

  • Linux Kernel 官方文档: The Linux Kernel documentation — The Linux Kernel documentation

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询