Linux

技术栈
工具链
oskernelshellserverunix

概览

Linux 技术栈概览

Linux 是 Linus Torvalds 于 1991 年发布的开源操作系统内核,加上 GNU 工具链形成完整的 GNU/Linux 操作系统。它运行在 100% 的 TOP500 超算、90%+ 的云服务器、所有 Android 手机上,是计算机专业的必修基础课。

解决什么问题

  • 专有操作系统昂贵且不可定制 → 开源自由,可深入修改任何部分
  • 服务器运维依赖 GUI → 命令行 + Shell 脚本自动化一切
  • 缺乏对操作系统内部的理解 → 源码级学习进程调度/内存管理/文件系统
  • 开发环境不一致 → 统一的 POSIX 兼容层

关键特性

  • 内核态/用户态分离:保护系统稳定性
  • 一切皆文件:设备/进程/网络连接统一为文件描述符
  • Shell:Bash/Zsh/Fish,管道 + 重定向组合工具
  • 包管理器:apt/dnf/pacman 统一软件管理
  • 文件权限模型:rwx + owner/group/other
  • 强大的网络栈:iptables/nftables/tc 流量控制
  • 容器原生:cgroups + namespace 支撑 Docker/K8s

安装

环境准备

Linux 无需传统「安装」——它本身就是操作系统。以下几种方式获取 Linux 环境:

方案一:WSL2(Windows 用户首选)

# PowerShell 管理员模式
wsl --install -d Ubuntu-22.04
# 重启后设置用户名密码即可

方案二:虚拟机

下载 VirtualBox + Ubuntu Desktop ISO:
https://ubuntu.com/download/desktop

方案三:云服务器

阿里云/腾讯云/AWS 免费试用,SSH 连接:

ssh username@your-server-ip

方案四:Docker

docker run -it ubuntu:22.04 bash

首次配置(以 Ubuntu 为例)

# 更新包列表
sudo apt update &;& sudo apt upgrade -y

# 安装基础工具
sudo apt install -y build-essential curl wget git vim htop

# 推荐安装 Zsh + Oh My Zsh
sudo apt install -y zsh
chsh -s $(which zsh)             # 设为默认 Shell
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

常见问题

Q1: Ubuntu 提示权限不足

普通用户加 sudo。避免直接使用 root 账户。文件权限:chmod +x script.sh 添加执行权限。

Q2: 软件源慢

换国内镜像源:sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list

Q3: SSH 连接被拒

检查:sudo systemctl status sshd;防火墙:sudo ufw allow 22;云服务器安全组放行 22 端口。

示例

Linux 例程:Shell 脚本——服务器资源监控

目标

写一个实用的 Bash 监控脚本,展示 Linux 管道、重定向、grep/awk/sed 核心技法。

完整脚本

#!/bin/bash
# monitor.sh —— 轻量服务器资源监控

set -euo pipefail  # 严格模式:遇错即停、未定义变量报错、管道失败报错

# ── 配置 ──
LOG_FILE="/tmp/monitor_$(date +%Y%m%d).log"
ALERT_CPU=80        # CPU 告警阈值 %
ALERT_MEM=90        # 内存告警阈值 %

# ── 工具函数 ──
timestamp() {
    date "+%Y-%m-%d %H:%M:%S"
}

log() {
    echo "[$(timestamp)] $*" | tee -a "$LOG_FILE"
}

# ── 监控项 ──
check_cpu() {
    # 从 /proc/stat 计算 CPU 使用率
    local cpu_line
    cpu_line=$(grep '^cpu ' /proc/stat)
    local user system idle
    read -r _ user _ system _ idle _ <;<< "$cpu_line"
    local total=$((user + system + idle))
    local used=$((user + system))

    # 等 1 秒再读一次(计算差值才能得百分比)
    sleep 1
    cpu_line=$(grep '^cpu ' /proc/stat)
    read -r _ user2 _ system2 _ idle2 _ <;<< "$cpu_line"
    local total2=$((user2 + system2 + idle2))
    local used2=$((user2 + system2))

    local cpu_pct=$(( 100 * (used2 - used) / (total2 - total) ))
    echo "$cpu_pct"
}

check_memory() {
    local total used free pct
    read -r total used free <;<< "$(free -m | awk '/^Mem:/ {print $2, $3, $4}')"
    pct=$(( used * 100 / total ))
    log "内存: ${used}MB / ${total}MB (${pct}%)"
    if [ "$pct" -ge "$ALERT_MEM" ]; then
        log "⚠️  内存使用率过高: ${pct}%"
    fi
}

check_disk() {
    df -h / /home 2>;/dev/null | awk 'NR>1 {
        gsub(/%/,"",$5)
        printf "磁盘 %s: %s / %s (%d%%)\n", $6, $3, $2, $5
        if ($5+0 >; 85) print "⚠️  磁盘空间不足: " $6
    }&#39; | while read -r line; do log "$line"; done
}

check_network() {
    local conns
    conns=$(ss -tun state established | tail -n +2 | wc -l)
    log "活跃 TCP 连接数: $conns"
}

check_top_processes() {
    log "=== TOP 5 进程(CPU)==="
    ps aux --sort=-%cpu | head -6 | tail -5 | while read -r line; do
        local user pid cpu mem cmd
        read -r user pid cpu mem _ _ _ _ _ _ _ cmd <;<< "$line"
        log "  PID=${pid} CPU=${cpu}% MEM=${mem}% CMD=${cmd:0:50}"
    done
}

# ── 主循环 ──
main() {
    log "======== 监控开始 ========"

    local cpu
    cpu=$(check_cpu)
    log "CPU 使用率: ${cpu}%"
    if [ "$cpu" -ge "$ALERT_CPU" ]; then
        log "⚠️  CPU 使用率过高: ${cpu}%"
    fi

    check_memory
    check_disk
    check_network
    check_top_processes

    log "======== 监控结束 ========"
}

# 如果传入 --watch 参数,循环执行
if [ "${1:-}" = "--watch" ]; then
    while true; do
        clear
        main
        sleep 5
    done
else
    main
fi

运行步骤

chmod +x monitor.sh
./monitor.sh           # 执行一次
./monitor.sh --watch   # 持续监控

预期输出

[2024-01-15 14:30:00] ======== 监控开始 ========
[2024-01-15 14:30:01] CPU 使用率: 23%
[2024-01-15 14:30:01] 内存: 2048MB / 8192MB (25%)
[2024-01-15 14:30:01] 磁盘 /: 45G / 100G (45%)
[2024-01-15 14:30:01] 活跃 TCP 连接数: 12
[2024-01-15 14:30:01] ======== 监控结束 ========

关键 Shell 技法

技法 示例
管道 `ps aux
重定向 echo log >> file.log 2>&1
命令替换 $(date)
Here String <<< "$variable"
条件判断 [ "$a" -ge 80 ]
循环读取 while read -r line; do ... done

教程

Linux 操作系统基础入门教程

第一章:Linux 文件系统

核心目录结构

/         根目录
├── /bin      基本命令(ls, cp, mv)
├── /boot    内核和引导文件
├── /dev     设备文件(一切皆文件!)
├── /etc     系统配置
├── /home    用户家目录
├── /lib     共享库
├── /proc    进程和内核信息(虚拟文件系统)
├── /tmp     临时文件
├── /usr     用户软件(bin, lib, share)
└── /var     可变数据(log, spool, cache)

一切皆文件

# 设备也是文件
ls -l /dev/sda        # 硬盘
ls -l /dev/tty        # 终端

# 进程也是文件
ls /proc/1            # PID 1 (systemd/init) 的目录

# 网络连接也是文件
ls /proc/self/fd      # 当前进程的文件描述符

第二章:文件权限

-rwxr-xr--  1 alice developers  4096 Jan 15 main.py
│├─┤├─┤├─┤
│ │  │  └── other: r--(其他人只读)
│ │  └───── group: r-x(组可读可执行)
│ └──────── owner: rwx(所有者全部权限)
└────────── 类型: -文件 d目录 l链接
chmod 755 script.sh   # rwxr-xr-x
chown user:group file # 改所有者

第三章:管道与重定向

管道是 Unix 哲学的体现——每个程序做好一件事,通过管道组合:

# 管道:前命令 stdout → 后命令 stdin
cat access.log | grep 404 | awk '{print $1}' | sort | uniq -c | sort -rn

# 重定向
cmd >; file      # stdout → file(覆盖)
cmd >;> file     # stdout → file(追加)
cmd 2>;&1        # stderr → stdout
cmd &;> file     # stdout + stderr → file
cmd <; file      # file → stdin

第四章:常用命令速查

类别 命令
文件 ls, cp, mv, rm, find, locate, stat
文本 cat, less, head, tail, grep, awk, sed
进程 ps, top/htop, kill, nice, nohup
网络 curl, wget, ss, nc, tcpdump, iptables
磁盘 df, du, mount, fdisk, lsblk
权限 chmod, chown, sudo, su
压缩 tar, gzip, zip, unzip

第五章:进程与信号

# 后台运行
long_running_task &;
nohup long_running_task &;    # 退出 Shell 也不停
disown                        # 已启动的任务转为后台

# 信号
kill -9 PID       # SIGKILL(强制杀)
kill -15 PID      # SIGTERM(优雅退出)
kill -STOP PID    # 暂停进程
kill -CONT PID    # 恢复进程

思考题

  1. 「一切皆文件」的设计哲学有什么好处?Windows 为什么没采用这种设计?
  2. hard link 和 symbolic link 的区别?删除原文件后两者各是什么状态?
  3. &&||; 在命令连接中有什么区别?
  4. 如何找出占用 8080 端口的进程并杀掉它?

参考资料

暂无参考文献