外观
Linux
引言
Linux 是一个开源的类 Unix 操作系统内核,由林纳斯·托瓦兹在 1991 年首次发布。作为现代计算基础设施的基石,Linux 以其稳定性、安全性和灵活性著称,广泛应用于服务器、嵌入式设备、超级计算机和个人电脑等领域。
体系架构
整体架构
Linux 采用分层架构,各组件之间通过清晰的接口进行通信:
应用程序
|
系统调用接口
|
Linux 内核
|
硬件抽象层
|
物理硬件内核空间与用户空间
用户空间
├── 应用程序 (进程)
├── 系统库 (glibc)
└── 运行环境
系统调用边界
↓
内核空间
├── 系统调用接口
├── 进程管理
├── 内存管理
├── 文件系统
├── 设备驱动
└── 网络栈核心组件
进程管理
Linux 使用进程和线程作为执行单元,通过调度器管理 CPU 时间分配。
进程状态转换:
新建 → 就绪 ↔ 运行 → 终止
↑
└── 等待/阻塞进程相关命令示例:
bash
# 查看进程树
pstree -p
# 实时进程监控
top
htop
# 进程信号发送
kill -TERM 1234
kill -KILL 5678内存管理
Linux 使用虚拟内存管理,为每个进程提供独立的地址空间。
虚拟内存布局:
0xFFFFFFFF
┌─────────────┐
│ 内核空间 │
├─────────────┤
│ 栈空间 │ ← 向下增长
├─────────────┤
│ 共享库 │
├─────────────┤
│ 堆空间 │ ← 向上增长
├─────────────┤
│ BSS段 │
├─────────────┤
│ 数据段 │
├─────────────┤
│ 代码段 │
└─────────────┘
0x00000000文件系统
Linux 采用统一的文件系统模型,“一切皆文件”是其核心哲学。
文件系统层次结构:
/
├── bin (基本命令)
├── etc (系统配置)
├── home (用户目录)
├── proc (进程信息)
├── sys (内核参数)
├── tmp (临时文件)
├── usr (用户程序)
└── var (可变数据)系统调用
文件操作系统调用
c
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
// 文件描述符操作
int open(const char *pathname, int flags, mode_t mode);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
int close(int fd);
// 示例:文件复制
int copy_file(const char *src, const char *dst) {
int src_fd = open(src, O_RDONLY);
int dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0644);
char buffer[4096];
ssize_t bytes_read;
while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) {
write(dst_fd, buffer, bytes_read);
}
close(src_fd);
close(dst_fd);
return 0;
}进程控制系统调用
c
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
// 进程创建和执行
pid_t fork(void);
int execve(const char *pathname, char *const argv[], char *const envp[]);
pid_t waitpid(pid_t pid, int *wstatus, int options);
// 信号处理
int kill(pid_t pid, int sig);
sighandler_t signal(int sig, sighandler_t handler);
// 示例:创建子进程
pid_t child_pid = fork();
if (child_pid == 0) {
// 子进程
execl("/bin/ls", "ls", "-l", NULL);
exit(1); // 如果exec失败
} else if (child_pid > 0) {
// 父进程
waitpid(child_pid, NULL, 0);
}网络系统调用
c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// 网络通信
int socket(int domain, int type, int protocol);
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int listen(int sockfd, int backlog);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
// 示例:TCP服务器
int create_tcp_server(int port) {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(port),
.sin_addr.s_addr = INADDR_ANY
};
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
listen(sockfd, 10);
return sockfd;
}Shell 编程
基础语法
bash
#!/bin/bash
# 变量定义和使用
name="Linux"
echo "Hello, $name!"
# 条件判断
if [ -f "/etc/passwd" ]; then
echo "文件存在"
elif [ -d "/etc" ]; then
echo "目录存在"
else
echo "都不存在"
fi
# 循环处理
for file in *.txt; do
echo "处理文件: $file"
done
# 函数定义
create_backup() {
local src=$1
local dst="${src}.bak"
cp "$src" "$dst"
echo "备份创建: $dst"
}高级脚本技巧
bash
#!/bin/bash
# 错误处理
set -euo pipefail
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> /var/log/myscript.log
}
# 信号处理
cleanup() {
log "收到中断信号,正在清理..."
rm -f /tmp/tempfile.*
exit 0
}
trap cleanup SIGINT SIGTERM
# 进程锁
LOCKFILE="/var/run/myscript.lock"
if [ -e "$LOCKFILE" ]; then
echo "脚本已在运行" >&2
exit 1
fi
echo $$ > "$LOCKFILE"
# 确保锁文件被删除
trap 'rm -f "$LOCKFILE"' EXIT系统管理
用户和权限管理
bash
# 用户管理
useradd -m -s /bin/bash newuser
usermod -aG wheel newuser
userdel -r olduser
# 权限管理
chmod 755 script.sh
chown user:group file.txt
chmod u+s executable # 设置SUID位
# ACL高级权限
setfacl -m u:username:rwx /path/to/dir
getfacl /path/to/dir软件包管理
APT (Debian/Ubuntu):
bash
# 更新软件源
apt update
# 安装软件
apt install nginx
# 搜索软件包
apt search python3
# 卸载软件
apt remove package-name
apt autoremoveYUM (RHEL/CentOS):
bash
# 安装软件
yum install httpd
# 更新系统
yum update
# 管理服务
systemctl start httpd
systemctl enable httpd网络配置
网络接口管理
bash
# 查看网络接口
ip addr show
ip link show
# 配置IP地址
ip addr add 192.168.1.100/24 dev eth0
ip route add default via 192.168.1.1
# 网络诊断
ping -c 4 google.com
traceroute google.com
netstat -tuln
ss -tuln防火墙配置
bash
# iptables 基础配置
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -P INPUT DROP
# firewalld (现代Linux)
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload性能监控
系统资源监控
bash
# 实时系统监控
top
htop
# 内存使用情况
free -h
cat /proc/meminfo
# 磁盘使用情况
df -h
du -sh /path/to/dir
# I/O 监控
iostat -x 1
iotop进程和性能分析
bash
# 进程监控
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10
# 系统负载
uptime
cat /proc/loadavg
# 性能分析工具
perf record -g ./program
perf report
# 跟踪系统调用
strace -f -o trace.log ./program内核模块
模块开发基础
c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple Linux driver");
static int __init hello_init(void) {
printk(KERN_INFO "Hello, Linux Kernel!\n");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye, Linux Kernel!\n");
}
module_init(hello_init);
module_exit(hello_exit);Makefile:
makefile
obj-m += hello.o
KDIR := /lib/modules/$(shell uname -r)/build
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean字符设备驱动
c
#include <linux/fs.h>
#include <linux/cdev.h>
static int device_open(struct inode *inode, struct file *file) {
printk(KERN_INFO "设备被打开\n");
return 0;
}
static ssize_t device_read(struct file *filp, char __user *buffer,
size_t length, loff_t *offset) {
const char *message = "Hello from kernel!\n";
size_t message_len = strlen(message);
if (*offset >= message_len)
return 0;
if (length > message_len - *offset)
length = message_len - *offset;
if (copy_to_user(buffer, message + *offset, length))
return -EFAULT;
*offset += length;
return length;
}
static struct file_operations fops = {
.open = device_open,
.read = device_read,
};容器技术
Docker 基础
dockerfile
# Dockerfile 示例
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
COPY . /app
WORKDIR /app
RUN pip3 install -r requirements.txt
EXPOSE 8000
CMD ["python3", "app.py"]容器管理命令:
bash
# 构建镜像
docker build -t myapp .
# 运行容器
docker run -d -p 8000:8000 --name myapp-container myapp
# 容器管理
docker ps
docker logs myapp-container
docker exec -it myapp-container bash系统调用封装
c
// 使用命名空间进行进程隔离
#define _GNU_SOURCE
#include <sched.h>
#include <sys/wait.h>
#include <sys/mount.h>
int create_container() {
int container_pid = clone(
container_main,
container_stack + STACK_SIZE,
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD,
NULL
);
return container_pid;
}
int container_main(void *arg) {
// 设置主机名
sethostname("container", 9);
// 挂载proc文件系统
mount("proc", "/proc", "proc", 0, NULL);
// 执行容器内的命令
execl("/bin/bash", "/bin/bash", NULL);
return 0;
}安全机制
SELinux 配置
bash
# SELinux 状态管理
getenforce
setenforce 1
# 上下文管理
ls -Z /var/www/html
chcon -t httpd_sys_content_t /path/to/file
# 策略管理
semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
restorecon -R /web能力管理
c
#include <sys/capability.h>
// 放弃不必要的权限
int drop_privileges() {
cap_t caps = cap_init();
// 只保留网络绑定能力
cap_value_t cap_list[] = { CAP_NET_BIND_SERVICE };
cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_list, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, 1, cap_list, CAP_SET);
if (cap_set_proc(caps) == -1) {
return -1;
}
cap_free(caps);
return 0;
}调试与诊断
核心转储分析
bash
# 启用核心转储
ulimit -c unlimited
echo "/tmp/core.%e.%p" > /proc/sys/kernel/core_pattern
# 分析核心转储
gdb /path/to/program /tmp/core.program.1234
# 在GDB中常用命令
bt # 查看调用栈
info locals # 查看局部变量
print var # 打印变量值系统日志分析
bash
# 查看系统日志
journalctl -f
tail -f /var/log/syslog
# 日志过滤
journalctl --since "2024-01-01" --until "2024-01-02"
journalctl -u nginx.service
# 自定义日志
logger -p local0.info "自定义日志消息"