云服务器买回来,登录进去之后只会敲 ls 和 cd,想装个软件发现没权限,想看日志发现文件几百兆,想查端口被谁占用又卡在 netstat 报 command not found——这大概是很多人刚接触 Linux 时的真实状态。Linux 命令不难,难的是零散:网上教程要么只讲单个命令不讲组合,要么直接上高深运维脚本,中间那块"能干活"的部分反而缺失。这篇文章按照"认知建立 → 环境准备 → 命令拆解 → 综合实战 → 排错清单"的顺序,把 Linux 系统操作和核心命令做一次系统梳理,每个命令都给出可复制的示例和预期输出,同时解释为什么这么用。零基础可以顺着往下读,有基础的可以直接跳到第 4 章之后当作速查手册,云计算方向的同学重点关注第 7、8、9 章的进程、网络和部署部分。
1. Linux 是什么:先建立正确的系统认知
1.1 内核、发行版与它们的关系
严格来说,Linux 只是内核(Kernel),负责管理 CPU 调度、内存分配、磁盘读写、网络收发这些最底层的事。我们日常敲的 ls、cd、grep 并不是内核的一部分,而是运行在内核之上的用户态程序,通常来自 GNU 工具集和各自的软件包。
内核加上 shell、基础命令、包管理器、系统服务,打包成一个完整可安装的系统,才叫发行版(Distribution)。理解这个分层很关键:
- 命令报
command not found,是用户态软件没装,不是内核坏了; - 系统卡死、OOM,是内核层面的资源问题,装命令解决不了;
- 不同发行版命令 90% 相同,差异主要集中在包管理器和配置文件路径上。
1.2 主流发行版与云计算的关系
实际工作中遇到最多的两类:
| 家族 | 代表发行版 | 包管理器 | 常见场景 |
|---|---|---|---|
| Debian 系 | Ubuntu、Debian | apt |
云主机、容器基础镜像、开发环境 |
| Red Hat 系 | CentOS、Rocky Linux、AlmaLinux、Fedora | yum / dnf |
企业服务器、传统 IDC 部署 |
容器镜像(Docker 镜像)绝大多数也基于这两类发行版构建,比如 ubuntu、debian、alpine、centos。所以学会一套命令,在云服务器、容器、本地虚拟机里基本通用,这也是 Linux 被称作"云计算地基"的原因——云平台的绝大多数 IaaS 计算实例,底层跑的就是 Linux 内核。
需要注意的是,CentOS 8 之后社区版本策略有较大调整,很多企业已迁移到 Rocky Linux 或 AlmaLinux。本文示例以 Ubuntu Server 和 CentOS 7 系列为例,两者的差异会在涉及处标注,具体版本请以你实际拿到的机器为准。
1.3 学习命令的正确顺序
很多新手一上来就背 awk 这种复杂命令,结果记住几天就忘了。更合理的顺序是:
- 先会定位:
pwd、ls、cd、find,搞清楚"我在哪、有什么、怎么找"。 - 再会读写:
cat、less、tail、vim,能看能改。 - 再会管理:权限
chmod、用户、进程ps、服务systemctl。 - 最后会组合:管道、重定向、
grep/sed/awk,把单个命令串成解决实际问题的流水线。
前两步大概一两天就能熟悉,第三步是分水岭,第四步是真正拉开差距的地方。下面按这个顺序展开。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备:三种零成本上手方式
2.1 方式一:本地虚拟机
适合想完整感受"装系统"过程的同学。安装 VirtualBox 或 VMware Workstation Player,下载 Ubuntu Server 或 Rocky Linux 的 ISO 镜像,分配 2 核 CPU、2GB 内存、20GB 磁盘即可流畅运行。
虚拟机的好处是可以随便折腾,rm -rf 删坏了直接重建快照。建议在装完系统、配置好 SSH 之后立刻打一个快照,作为"干净基线"。
2.2 方式二:Windows 内置的 Linux 子系统
Windows 10/11 自带 WSL,开箱即用,不需要重启切换系统。以管理员身份打开 PowerShell,执行:
powershell复制wsl --install -d Ubuntu
首次安装完成后需要重启,然后按提示设置用户名和密码。之后在开始菜单里搜索 Ubuntu 即可打开终端。
WSL 的特点是文件系统与 Windows 互通,在 WSL 里可以直接访问 /mnt/c/Users/你的用户名/。但要注意:WSL 没有 systemd(新版本可通过配置开启),第 7 章的 systemctl 相关内容在 WSL 里可能无法演示,这一点需要提前知道。
2.3 方式三:云服务器
如果有云服务器,直接用 SSH 登录最贴近生产环境。购买时选择 Ubuntu 或 CentOS 镜像,安全组放行 22 端口,然后用终端连接:
bash复制ssh root@你的服务器公网IP
首次登录会提示确认主机指纹,输入 yes 后输入密码即可。相比本地环境,云服务器的优势是真实的公网网络环境,做第 8 章的端口和服务测试更有意义。
安全提醒:云服务器默认开放公网 SSH 是有风险的,生产环境务必改用密钥登录、禁用 root 直接登录、限制来源 IP。这些属于授权范围内的正常加固操作,但任何针对非自有服务器的探测和尝试都是不允许的。
2.4 首次登录后的环境自查
不管用哪种方式,登录后先跑一遍这几条命令,确认环境状态:
bash复制# 查看内核版本和系统架构
uname -a
# 查看发行版信息(Ubuntu/Debian 系)
cat /etc/os-release
# 查看当前登录用户
whoami
# 查看当前所在目录
pwd
# 查看磁盘使用情况
df -h
预期输出大致如下(df -h 部分):
code复制Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 6.2G 32G 17% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
Use% 这一列在生产环境里要经常看,超过 85% 就要开始处理了,这个问题在第 10 章会详细讲。
3. 目录结构与文件系统:先认清地图
3.1 "一切皆文件"的哲学
Linux 把设备、磁盘、网络套接字甚至内核参数都抽象成文件来管理。比如 /dev/sda 是磁盘,/proc/cpuinfo 是 CPU 信息,/etc/ 下几乎都是纯文本配置。这个设计的好处是:你只要学会操作文件,就学会了一大半系统管理。看硬件信息用 cat,改配置用编辑器,备份配置就是 cp。
3.2 根目录下各目录的职责
bash复制ls -l /
典型输出:
code复制bin -> usr/bin
boot
dev
etc
home
opt
proc
root
run
srv
sys
tmp
usr
var
关键目录的含义:
| 目录 | 作用 | 常见操作 |
|---|---|---|
/etc |
系统和软件配置文件 | 改 nginx、ssh、hosts 配置 |
/var |
经常变化的数据,日志在 /var/log |
查日志、清日志 |
/home |
普通用户家目录 | 存放个人文件 |
/root |
root 用户家目录 | 管理员私有文件 |
/tmp |
临时文件,重启可能清空 | 放临时脚本和包 |
/usr |
用户程序与库文件,/usr/bin 放命令 |
装软件 |
/opt |
第三方大型软件 | 手动安装的软件 |
/proc、/sys |
内核和进程的虚拟文件系统 | 查系统状态 |
3.3 绝对路径与相对路径
- 绝对路径:从
/开始,比如/var/log/nginx/access.log,在哪个目录下执行都指向同一个文件。 - 相对路径:从当前位置开始,比如
logs/access.log或../conf/nginx.conf。
几个路径符号必须记住:
.当前目录..上一级目录~当前用户家目录-上一次所在目录(配合cd -快速来回切换)
写脚本时强烈建议用绝对路径,因为脚本被 cron 或 systemd 调用时,工作目录可能完全不是你以为的位置,这是新手脚本"手动能跑、定时不跑"的头号原因。
3.4 挂载与磁盘信息
Linux 没有 Windows 那种 C/D 盘符,所有存储都挂在根目录下的某个位置。查看挂载情况:
bash复制# 查看已挂载的文件系统
mount | column -t
# 查看磁盘分区与文件系统类型
lsblk -f
lsblk -f 会显示设备名、文件系统类型(ext4、xfs 等)、挂载点。云服务器上新购的数据盘通常需要自己分区、格式化、挂载,这一步务必确认盘是空的,格式化会清空数据。
4. 文件与目录操作核心命令
4.1 查看与切换:ls、cd、pwd
ls 是最常用的命令,参数组合比命令本身更重要:
bash复制ls # 简单列出
ls -l # 长格式,显示权限、所有者、大小、时间
ls -lh # 大小带单位(K/M/G),更易读
ls -a # 显示隐藏文件(以 . 开头)
ls -lt # 按修改时间倒序,最新的在前
ls -ltr # 按修改时间正序,最新的在最后(看日志常用)
ls -R # 递归列出子目录
ls -l 的输出要会读:
code复制-rw-r--r-- 1 root root 1234 Jul 10 09:30 app.conf
drwxr-xr-x 2 www www 4096 Jul 10 09:25 html
从左到右依次是:文件类型与权限(- 普通文件,d 目录,l 软链接)、硬链接数、所有者、所属组、大小(字节)、最后修改时间、文件名。
4.2 创建与删除:touch、mkdir、rm
bash复制# 创建空文件,或更新已有文件的时间戳
touch test.log
# 创建多级目录,-p 表示父目录不存在时自动创建
mkdir -p /data/app/logs
# 创建目录并直接给出权限
mkdir -m 750 /data/secure
# 删除文件
rm test.log
# 删除目录及其内容,递归加强制
rm -rf /data/old_app
rm -rf 是 Linux 里最危险的命令,没有之一。 它不经过回收站,删掉即消失。几个必须养成的习惯:
- 执行前先用
ls把同样的路径列一遍,确认目标对不对; - 变量路径先用
echo打印,确认展开结果再执行; - 生产环境加别名保护,在
~/.bashrc里加alias rm='rm -i'; - 重要目录操作前先备份,哪怕只是
cp -a到/tmp。
顺带一提,rm -rf / 和 rm -rf /* 这类命令在多数现代系统上会有保护提示,但不要依赖这个保护,rm -rf $DIR/* 里 $DIR 为空时会退化成删除根目录,这类事故每年都在发生。
4.3 复制与移动:cp、mv、ln
bash复制# 复制文件
cp app.conf app.conf.bak
# 复制目录,-r 递归,-a 保留权限和时间等属性(备份首选)
cp -a /data/app /backup/app_20250901
# 移动或重命名
mv old_name.txt new_name.txt
mv /data/tmp/*.log /data/archive/
# 创建软链接(相当于快捷方式,源文件删除后链接失效)
ln -s /opt/app/current/config.yml /etc/app/config.yml
# 创建硬链接(共享同一份数据,删除任一不影响)
ln /data/file.txt /data/file_link.txt
软链接在部署里用得极多,比如发布新版本时只改软链接指向,回滚就是把链接指回去,比反复复制文件快得多。
4.4 查看文件内容:cat、less、head、tail
bash复制# 一次性输出全部内容,适合小文件
cat /etc/hosts
# 分页查看,支持上下翻页和搜索,适合大文件
less /var/log/syslog
# 在 less 中:/关键词 搜索,n 下一个,q 退出
# 看前 20 行
head -n 20 access.log
# 看最后 50 行,排查日志首选
tail -n 50 access.log
# 实时跟踪日志新增内容,Ctrl+C 退出
tail -f /var/log/nginx/access.log
# 实时跟踪并过滤关键词
tail -f app.log | grep -i error
tail -f 是排障时使用频率最高的命令之一,配合 grep 能在复现问题时立刻看到报错。如果日志文件被切割(logrotate),-f 可能跟丢文件,改用 tail -F 会根据文件名重新打开。
4.5 查找文件:find 与通配符
bash复制# 按名称查找
find /var/log -name "*.log"
# 忽略大小写
find / -iname "nginx.conf"
# 按类型查找:f 文件,d 目录
find /data -type d -name "logs"
# 按修改时间查找,+7 表示 7 天以前
find /var/log -name "*.log" -mtime +7
# 按大小查找,大于 100M 的文件
find / -type f -size +100M
# 找到后直接删除(先不加 -delete 跑一遍确认结果!)
find /tmp -name "*.tmp" -mtime +3 -delete
# 对找到的文件批量执行命令
find /data/logs -name "*.log" -exec gzip {} \;
find 的参数多但逻辑统一:在哪个目录找 → 找什么 → 满足什么条件 → 做什么动作。生产上清理日志、定位大文件、批量改权限都靠它,比 ls 加肉眼筛选可靠得多。
通配符补充几个常用写法:* 匹配任意字符,? 匹配单个字符,[abc] 匹配括号内任一字符,{a,b} 花括号展开(注意这不是通配符,是 shell 的展开功能)。
5. 权限、用户与所有者
5.1 权限位的读法
ls -l 第一列的 10 个字符,第 1 位是文件类型,后面 9 位分三组:
code复制- rwx r-x r--
| | |
所有者 所属组 其他人
r(read,4):读文件内容、列目录w(write,2):改文件内容、在目录内增删文件x(execute,1):执行文件、进入目录
这里有个高频误区:目录没有 x 权限就无法 cd 进去,只有 r 权限只能列出文件名但看不到详情。给目录配权限时 x 不能省。
5.2 chmod:符号法与数字法
bash复制# 数字法:r=4 w=2 x=1,三组相加
chmod 755 script.sh # rwxr-xr-x
chmod 644 config.conf # rw-r--r--
chmod 600 id_rsa # rw-------,私钥必须是这个权限
# 符号法:u 所有者,g 所属组,o 其他人,a 全部
chmod u+x script.sh
chmod g-w file.txt
chmod o=r file.txt
chmod -R 750 /data/app # -R 递归,谨慎使用
常见权限对照:
| 权限 | 数字 | 含义 | 典型用途 |
|---|---|---|---|
| rwxr-xr-x | 755 | 所有者全权,其他人可读可执行 | 目录、可执行脚本 |
| rw-r--r-- | 644 | 所有者可读写,其他人只读 | 普通配置文件 |
| rw------- | 600 | 仅所有者可读写 | 私钥、密码文件 |
| rwx------ | 700 | 仅所有者可进入 | 私有家目录 |
关于 chmod -R 777: 这是新手最爱的"万能修复",但它等于让任何用户都能改你的文件,是明确的安全隐患。正确做法是定位到底是谁没有权限,只补必要的那一位。
5.3 chown 与 chgrp:改归属
bash复制# 改所有者
chown www-data /data/app
# 同时改所有者和所属组
chown www-data:www-data /data/app
# 递归修改
chown -R www-data:www-data /var/www/html
最常见的场景是:用 root 解压了一个网站包,结果 nginx 以 www-data 身份运行读不到文件,报 403。原因就是文件所有者是 root、权限是 600/700。修法是 chown -R 改成 Web 用户,而不是无脑 777。
5.4 用户管理与 sudo 最小权限
bash复制# 查看当前用户和所属组
id
# 新建用户并创建家目录
useradd -m -s /bin/bash deploy
# 设置密码(会提示输入两次)
passwd deploy
# 加入附加组
usermod -aG sudo deploy # Ubuntu 系
usermod -aG wheel deploy # Red Hat 系
# 切换用户
su - deploy
生产环境的原则是最小权限:日常用普通用户 + sudo 执行管理操作,不给所有人 root 密码。sudo 的授权范围在 /etc/sudoers 里配置,编辑时务必用 visudo,它会在保存前做语法检查,避免写错导致所有人都无法提权。
6. 文本处理与管道:把命令串起来
6.1 重定向与管道的基础
Linux 每个进程默认有三个流:标准输入(0)、标准输出(1)、标准错误(2)。
bash复制# 覆盖写入
echo "hello" > a.txt
# 追加写入
echo "world" >> a.txt
# 把错误输出重定向到文件
ls /notexist 2> err.log
# 标准输出和错误一起重定向
bash deploy.sh > out.log 2>&1
# 丢弃输出(常用于 cron 任务里屏蔽无关日志)
command > /dev/null 2>&1
# 管道:前一个命令的输出作为后一个命令的输入
ps aux | grep nginx
2>&1 的顺序很重要,必须写在 > 之后,它的意思是"把错误流指向标准输出当前指向的位置"。写成 2>&1 > file 就完全不是那个效果了。
6.2 grep:文本搜索
bash复制# 基本搜索
grep "error" app.log
# 忽略大小写 + 显示行号
grep -in "error" app.log
# 递归搜索目录
grep -rn "timeout" /etc/nginx/
# 反向匹配:不含关键词的行
grep -v "^#" nginx.conf
# 统计匹配行数
grep -c "ERROR" app.log
# 只输出匹配到的内容本身
grep -o "user=[a-z]*" app.log
grep -v "^#" 过滤注释行是读配置文件的必备技巧,能快速看清有效配置。
6.3 sed:流式编辑
bash复制# 替换并输出到屏幕(不改原文件)
sed 's/8080/9090/' app.conf
# 全局替换(不加 g 只替换每行第一处)
sed 's/8080/9090/g' app.conf
# 直接修改原文件,建议先备份
sed -i.bak 's/8080/9090/g' app.conf
# 删除空行
sed '/^$/d' file.txt
# 打印第 10 到 20 行
sed -n '10,20p' file.txt
sed -i 是直接改文件的操作,生产环境改配置前一定先备份(-i.bak 会自动生成 .bak 文件),改完用 nginx -t 之类的检查命令验证语法再重载。
6.4 awk:按列处理
bash复制# 打印第一列和第三列
awk '{print $1, $3}' file.txt
# 指定分隔符(默认是空格或制表符)
awk -F: '{print $1}' /etc/passwd
# 按条件过滤
awk '$9 == 500 {print $0}' access.log
# 求和
awk '{sum += $5} END {print sum}' numbers.txt
# 带行号输出
awk '{print NR": "$0}' file.txt
awk 的核心是"按行读取、按列处理、可加条件、可做统计",日志分析场景基本离不开它。
6.5 组合实战:分析访问日志
假设有一份 Nginx 访问日志 /var/log/nginx/access.log,标准格式第一列是客户端 IP,第九列是状态码,第七列是请求路径。几个高频分析需求:
bash复制# 统计访问量前 10 的 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -n 10
# 统计各状态码数量
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 找出所有 502 请求的时间
awk '$9 == 502 {print $4}' /var/log/nginx/access.log | head
# 统计访问量最高的 10 个路径
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -n 10
以第一条为例拆解流程:
awk '{print $1}'取出第一列 IP;sort排序,把相同 IP 排到一起;uniq -c相邻去重并计数(所以必须先 sort);sort -rn按数字倒序;head -n 10取前十。
这条流水线是日志分析的模板,换成 $9 就是状态码分布,换成 $7 就是热门路径。理解它比背下来更重要。
7. 进程、服务与系统状态
7.1 ps 与 top:看谁在跑
bash复制# 查看所有进程(BSD 风格)
ps aux
# 查看所有进程(System V 风格),含 PPID
ps -ef
# 查找特定进程
ps -ef | grep java
# 树形展示父子进程
ps -ef --forest
# 按内存占用排序取前 10
ps aux --sort=-%mem | head -n 11
ps aux 输出里的关键列:USER 用户、PID 进程号、%CPU/%MEM 资源占用、STAT 状态(R 运行、S 睡眠、Z 僵尸)、COMMAND 启动命令。
top 是动态视图,交互键很实用:P 按 CPU 排序,M 按内存排序,1 展开各核,q 退出。如果系统装了 htop,界面更友好,可以用 apt install htop 或 yum install htop 安装。
7.2 kill:结束进程
bash复制# 优雅终止,发送 SIGTERM(15),进程可做清理
kill 12345
# 强制终止,发送 SIGKILL(9),进程无法拦截
kill -9 12345
# 按名称批量结束
pkill -f "python app.py"
顺序原则:先 kill 再 kill -9。直接 -9 会让进程来不及写日志、关连接、落盘数据,可能造成数据不一致。只有进程卡死无响应时才用强制手段。
7.3 systemctl:服务管理
现代发行版统一用 systemd 管理服务,命令高度一致:
bash复制# 查看服务状态(最常用)
systemctl status nginx
# 启动 / 停止 / 重启
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
# 重载配置,不中断服务(改了配置优先用这个)
systemctl reload nginx
# 设置开机自启 / 取消
systemctl enable nginx
systemctl disable nginx
# 查看是否开机自启
systemctl is-enabled nginx
# 列出所有运行中的服务
systemctl list-units --type=service --state=running
# 查看服务日志(systemd 托管服务的日志在 journal 里)
journalctl -u nginx -n 50 --no-pager
journalctl -u nginx -f
一个高频坑:systemctl start 成功不代表服务一直活着,如果启动后立刻崩溃,status 会显示 failed,此时用 journalctl -u 服务名 -n 100 看具体报错,比翻文件日志更快。
7.4 crontab:定时任务
bash复制# 编辑当前用户的定时任务
crontab -e
# 查看
crontab -l
# 删除全部
crontab -r
格式是五段加命令:
code复制分 时 日 月 周 命令
* * * * * command
示例:
bash复制# 每天凌晨 2 点备份数据库
0 2 * * * /bin/bash /data/scripts/backup.sh >> /data/logs/backup.log 2>&1
# 每 5 分钟检查一次服务
*/5 * * * * /usr/bin/systemctl is-active nginx || /usr/bin/systemctl restart nginx
# 每周一 3:30 清理 7 天前的日志
30 3 * * 1 find /data/logs -name "*.log" -mtime +7 -delete
定时任务最常见的三个问题:路径用相对路径导致找不到文件、环境变量缺失导致命令找不到(cron 的 PATH 很短,建议全部写绝对路径)、输出没重定向导致邮件堆积。这三条记住能省很多排查时间。
7.5 磁盘与内存排查
bash复制# 磁盘整体使用率
df -h
# 当前目录下各子目录大小,按大小排序
du -sh * | sort -rh | head -n 10
# 找出根目录下最大的目录(慢,但有效)
du -h --max-depth=1 / 2>/dev/null | sort -rh | head
# 内存使用
free -h
# 已删除但被进程占用的文件(磁盘满但 du 查不出来时用)
lsof | grep deleted
最后一条非常关键:磁盘显示满但 du 统计不出来,几乎都是因为有进程还持有已删除文件的句柄。此时重启对应进程就能释放空间,不需要重启整台机器。
8. 网络与远程管理
8.1 查看 IP、端口与连通性
bash复制# 查看网卡和 IP(现代发行版推荐 ip 命令)
ip addr show
ip a
# 查看路由
ip route
# 查看监听端口(ss 已取代 netstat)
ss -tunlp
# 只看某个端口
ss -tunlp | grep 8080
# 测试连通性
ping -c 4 www.example.com
# 测试端口是否可通(需要装 telnet 或用 nc)
nc -zv 127.0.0.1 8080
# 域名解析
dig www.example.com
nslookup www.example.com
ss -tunlp 输出里的 State 是 LISTEN 表示在监听,Local Address:Port 里 0.0.0.0:80 表示监听所有网卡,127.0.0.1:8080 表示只监听本机(外部访问不到)。很多"服务启动了但外网访问不了"的问题,根源就是绑定了 127.0.0.1。
8.2 curl 与 wget:调试利器
bash复制# 发 GET 请求,只显示响应头
curl -I http://127.0.0.1:8080
# 显示详细连接过程,排查超时用
curl -v http://127.0.0.1:8080
# 发 POST JSON
curl -X POST http://127.0.0.1:8080/api/user \
-H "Content-Type: application/json" \
-d '{"name":"test","age":18}'
# 设置超时,避免卡死
curl --connect-timeout 3 --max-time 10 http://127.0.0.1:8080
# 下载文件
wget https://example.com/file.tar.gz
wget -O custom_name.tar.gz https://example.com/file.tar.gz
curl -v 能看到 DNS 解析、TCP 连接、TLS 握手、请求头、响应头全过程,是判断"卡在哪一步"的最快方式。
8.3 ssh 与 scp:远程操作
bash复制# 登录
ssh user@192.168.1.100
# 指定端口
ssh -p 2222 user@192.168.1.100
# 上传文件到远程
scp ./app.jar user@192.168.1.100:/data/app/
# 从远程下载
scp user@192.168.1.100:/var/log/app.log ./
# 上传整个目录
scp -r ./dist user@192.168.1.100:/data/www/
# 本地端口转发到远程(把远程 3306 映射到本地 13306)
ssh -L 13306:127.0.0.1:3306 user@192.168.1.100
建议配置免密登录:本地执行 ssh-keygen -t rsa 生成密钥,再用 ssh-copy-id user@host 把公钥传到目标机。免密之后 scp、rsync、自动化脚本才能顺畅运行。私钥文件权限必须是 600,否则 SSH 会拒绝使用。
8.4 防火墙放行端口
bash复制# Ubuntu(ufw)
ufw status
ufw allow 8080/tcp
ufw reload
# CentOS 7(firewalld)
firewall-cmd --state
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
请注意顺序:--permanent 是写入永久配置,必须再执行 --reload 才生效;如果只执行 --add-port 不加 --permanent,重启后配置丢失。
云服务器还有一层安全组,这是平台侧的网络访问控制,和系统内防火墙是两回事。服务启动、端口监听、系统防火墙、云安全组四层都通了,外网才能访问——排错时按这个顺序逐个确认。
9. 软件包管理与部署实战
9.1 apt 与 yum/dnf
bash复制# Debian / Ubuntu
apt update # 更新软件源索引
apt upgrade -y # 升级已安装软件
apt install -y nginx # 安装
apt remove nginx # 卸载(保留配置)
apt purge nginx # 卸载并删除配置
apt search nginx # 搜索
apt list --installed # 已安装列表
# CentOS 7
yum install -y nginx
yum remove nginx
yum search nginx
# CentOS 8+ / Rocky / Alma
dnf install -y nginx
关键区别:apt install 前需要 apt update 更新索引;yum install 会自动处理依赖和索引。装完软件后,用 which nginx 确认可执行文件路径,用 nginx -v 确认版本。
9.2 实战目标与目录规划
下面做一个完整的部署练习:用 Nginx 托管一个静态站点,并用 systemd 托管一个自写的后台脚本。这是云计算日常最常见的两类操作。
目录规划:
code复制/data/
├── www/
│ └── demo/ # 站点根目录
│ └── index.html
├── app/
│ └── heartbeat.sh # 后台脚本
└── logs/
└── heartbeat.log
先建目录并设权限:
bash复制sudo mkdir -p /data/www/demo /data/app /data/logs
sudo chown -R $USER:$USER /data
chmod 755 /data/www/demo
9.3 安装并配置 Nginx
bash复制sudo apt update
sudo apt install -y nginx
安装完确认状态:
bash复制systemctl status nginx --no-pager
ss -tunlp | grep :80
curl -I http://127.0.0.1
新建站点配置文件 /etc/nginx/conf.d/demo.conf:
nginx复制server {
listen 80;
server_name _;
root /data/www/demo;
index index.html;
access_log /var/log/nginx/demo_access.log;
error_log /var/log/nginx/demo_error.log;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|png|css|js)$ {
expires 7d;
add_header Cache-Control "public";
}
}
写首页文件:
bash复制cat > /data/www/demo/index.html <<'EOF'
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Linux 部署练习</title>
</head>
<body>
<h1>Hello Linux</h1>
<p>静态站点部署成功</p>
</body>
</html>
EOF
配置检查 → 重载 → 验证:
bash复制sudo nginx -t
sudo systemctl reload nginx
curl -I http://127.0.0.1/
curl 返回 HTTP/1.1 200 OK 说明配置生效。如果返回 403,按第 10 章的权限排查流程处理;如果返回 404,检查 root 路径和文件名是否拼错。
9.4 用 systemd 托管后台脚本
自己写的脚本直接 nohup 跑在后台,机器重启就没了,也不方便看状态。标准做法是写一个 systemd 单元文件。
创建脚本 /data/app/heartbeat.sh:
bash复制#!/bin/bash
# 每 30 秒写一行心跳日志,用于演示服务托管
LOG_FILE=/data/logs/heartbeat.log
while true; do
echo "$(date '+%Y-%m-%d %H:%M:%S') heartbeat ok" >> "$LOG_FILE"
sleep 30
done
赋执行权限:
bash复制chmod +x /data/app/heartbeat.sh
创建 /etc/systemd/system/heartbeat.service:
ini复制[Unit]
Description=Heartbeat Writer Service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/bin/bash /data/app/heartbeat.sh
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
关键参数说明:
Type=simple:前台运行型服务,最常用;ExecStart:必须是绝对路径,这是手工能跑、systemd 跑不了的第一大原因;Restart=always:进程退出后 5 秒自动重启,保证常驻;WantedBy=multi-user.target:enable时会链接到多用户启动目标,实现开机自启。
加载并启动:
bash复制sudo systemctl daemon-reload
sudo systemctl start heartbeat
sudo systemctl enable heartbeat
sudo systemctl status heartbeat --no-pager
9.5 结果验证与日志查看
bash复制# 确认服务处于 active (running)
systemctl is-active heartbeat
# 查看脚本写的日志
tail -n 5 /data/logs/heartbeat.log
# 查看 systemd 收集的日志
journalctl -u heartbeat -n 20 --no-pager
预期日志内容:
code复制2026-09-01 10:00:00 heartbeat ok
2026-09-01 10:00:30 heartbeat ok
2026-09-01 10:01:00 heartbeat ok
到这里,静态站点、后台服务、日志查看、开机自启这一套完整流程就跑通了。这个过程覆盖了日常运维 80% 的基础动作:装包、配置、启服务、看日志、验端口。
如果想再进一步,可以试试用 tar 打包备份站点目录:
bash复制# 打包
tar -czvf /data/backup/demo_$(date +%Y%m%d).tar.gz -C /data/www demo
# 查看包内容(不解压)
tar -tzvf /data/backup/demo_20260901.tar.gz
# 解压到指定目录
tar -xzvf /data/backup/demo_20260901.tar.gz -C /data/restore/
-c 创建、-x 解压、-t 查看、-z gzip 压缩、-v 显示过程、-f 指定文件名且必须放在最后。这六个参数记住,打包解压就不会再查文档。
10. 常见问题与排查清单
10.1 命令找不到:command not found
现象:执行 netstat、ifconfig、tree 等提示找不到命令。
原因有两类:一是软件确实没装,二是软件装了但不在 PATH 里。排查步骤:
bash复制# 1. 确认命令是否在系统里
which netstat
type netstat
# 2. 查是哪个包提供(Debian 系)
apt-file search bin/netstat
# 3. 安装对应包
apt install -y net-tools
# 4. 查看 PATH
echo $PATH
现代发行版里 netstat 已被 ss 取代,ifconfig 已被 ip 取代,不是系统坏了,而是工具换代。写脚本时优先用新命令,兼容性更好。
10.2 权限被拒绝:Permission denied
这是新手遇到最多的报错,按下面顺序查:
bash复制# 1. 看当前用户
whoami
id
# 2. 看目标文件权限和所有者
ls -l /path/to/file
# 3. 看上级目录是否有 x 权限(很容易被忽略)
namei -l /path/to/file
namei -l 会把路径上每一级目录的权限都列出来,一眼看出是哪一层断了。常见场景:文件本身是 755,但父目录是 700 且不属于当前用户,照样进不去。
如果是服务报错,还要确认运行用户的身份。Nginx 以 www-data 运行,你改的是 root 的文件,那自然读不到。
10.3 磁盘空间不足:No space left on device
bash复制# 1. 看哪个分区满了
df -h
# 2. 找大目录
du -h --max-depth=1 / 2>/dev/null | sort -rh | head
# 3. 找大文件
find / -type f -size +500M 2>/dev/null
# 4. 检查被删除但仍被占用的文件
lsof | grep deleted
# 5. 清理日志(不要直接删,用清空或按天删)
truncate -s 0 /var/log/nginx/access.log
find /var/log -name "*.log" -mtime +7 -delete
不要直接 rm 正在被写入的日志文件,因为进程还持有句柄,空间不会释放,而且会丢失后续日志。正确做法是 truncate 清空,或者配好 logrotate 做切割。
10.4 端口被占用:Address already in use
bash复制# 1. 找出占用端口的进程
ss -tunlp | grep 8080
lsof -i:8080
# 2. 确认这个进程是什么
ps -ef | grep <PID>
# 3. 决定是停掉它还是换端口
kill <PID>
也可能是上一次启动的残留进程没退干净,或者 TIME_WAIT 状态连接过多。前者 kill 掉,后者可以调整内核参数,但生产环境改内核参数要评估影响。
10.5 排查速查表
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 命令找不到 | 包未安装 / PATH 不含该路径 | which、装包、检查 PATH |
| Permission denied | 文件权限、目录 x 位、运行用户不对 | ls -l + namei -l 逐级排查 |
| 服务启动即 failed | 配置语法错、路径写错、端口冲突 | systemctl status + journalctl -u |
| 外网访问不了 | 服务绑 127.0.0.1、防火墙、安全组 | 依次查监听地址、防火墙、安全组 |
| 磁盘满 | 日志暴涨、被删文件未释放 | df -h → du → lsof | grep deleted |
| 定时任务不执行 | 相对路径、环境变量、脚本无执行权限 | 全部改绝对路径、加重定向看日志 |
| 中文乱码 | locale 未设置 | locale 检查,必要时设置 LANG=zh_CN.UTF-8 |
sudo 提权失败 |
用户不在 sudo/wheel 组 | usermod -aG 加组后重新登录 |
| 修改配置不生效 | 没 reload、改错文件、多份配置冲突 | 先 -t 检查,再 reload,确认生效文件路径 |
11. 最佳实践与学习路线
11.1 命令使用习惯
- 不确定就先看:
man 命令、命令 --help是最权威的文档,比搜索引擎快。 - 危险操作先 echo:任何带变量和通配符的
rm、mv,先用echo打印展开结果。 - 改配置先备份:
cp app.conf app.conf.bak,或sed -i.bak,改完用工具的语法检查验证。 - reload 优于 restart:Nginx、MySQL 等支持
reload的服务,改配置后优先平滑重载,避免连接中断。 - 善用历史与搜索:
history | grep ssh、Ctrl+R反查,比重新敲一遍高效。
11.2 生产环境的几条红线
- 权限最小化:不给 777,不给全员 root,按角色分配。
- 删除前确认可恢复:重要数据先打包备份,
rm -rf前跑一遍ls验证路径。 - 变更留痕:改了什么、为什么改、怎么回滚,写清楚。配置文件建议纳入版本管理。
- 先在测试环境验证:尤其是涉及防火墙、SSH 配置、内核参数的变更,改错可能导致机器登不上。
- 保持日志可查:别把日志全丢掉,出问题时它就是唯一的证据链。
举个具体的风险案例:修改 SSH 配置时改错端口或禁用了密码登录,如果当前会话一断开就再也连不上。正确做法是保留一个已登录会话不关,新开窗口验证能登录成功后再关闭旧会话。
11.3 学习路线建议
第一阶段打基础,把这些命令练到不用查文档:ls、cd、pwd、cp、mv、rm、mkdir、cat、less、tail、grep、find、chmod、chown、ps、kill、df、du、tar。
第二阶段学服务与网络:systemctl、ss、curl、ssh、scp、crontab、防火墙,目标是能独立部署一个 Web 服务并排障。
第三阶段补文本处理能力:sed、awk、管道组合,目标是能写日志分析脚本。这一步是分水岭,能不能从"会用命令"变成"能解决问题",主要看这里。
第四阶段进入自动化与运维:Shell 脚本编写、rsync 同步、日志切割、监控告警、容器基础。这些内容建立在前面三阶段扎实的前提下,跳步学会很痛苦。
练习建议:在虚拟机或云服务器上搭一套 LNMP 或 Nginx + Python 环境,从装系统开始,全程用命令行完成,不留图形界面。遇到报错先自己查 journalctl 和日志文件,实在解决不了再搜索。这个过程比看十篇教程都有效。
最后提醒一句:Linux 命令数量多,但真正高频的就那三四十个。把它们练熟,配合 man 手册和日志工具,绝大部分日常工作都能覆盖。剩下的冷门参数遇到再查,完全来得及。
