1. 第二期学习清单:从“勉强能跑”到“出事会查”
先说个背景。第一期那会儿我基本就是对着教程敲命令,装个软件、解个压、改个权限,能跑起来就觉得自己挺行了。但真到用的时候才发现,能用和会用之间差着十万八千里。就拿这次第二期来说,我给自己定的目标是:不再跟着别人的命令走,而是遇到问题能自己判断该查什么、该用什么工具、为什么这么用。
这一期我整理的热搜词就很能说明问题——linux常用命令、linux新建用户、linux安装docker、linux删除文件夹命令、linux find、linux scp命令、linux sed、linux安装nginx、linux系统安装、linux面试题测试,这些词看似零散,实际上涵盖了日常运维和开发中最常碰到的几个场景:账号管理、文件操作、远程传输、服务部署、系统排查、面试复盘。我按这个逻辑把学习内容拆成了五个模块,后面每个模块都配了实操记录和踩坑笔记,不是那种“复制粘贴能跑就行”的写法,而是把命令背后的原理和排查思路一起捋清楚。
这篇博文适合谁看?如果你是刚接触Linux、正准备系统性补课的同学,或者你已经会用一些基础命令但遇到问题还是懵、只能到处搜答案的“半新手”,这篇文章应该能帮上忙。我会尽量把每一步的命令、输出、坑点都写出来,大家照着练一遍,比单看命令大全有用得多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 账号与文件操作:新建用户和删文件夹踩出的权限认知
2.1 新建用户的完整流程,比想象中多三步
热搜词里有“linux新建用户”,看起来是个特别基础的操作,无非就是useradd加个用户。但我在实际走了一遍之后发现,如果只是useradd一个用户名就完事,后面几乎一定会踩坑。
我本地的测试环境是CentOS 7.9,操作如下:
bash复制useradd zhangsan
passwd zhangsan
passwd会交互式让你输入两次密码,这个没问题。问题在于,useradd默认情况下不会创建用户的主目录,也不会设置登录Shell。你切到zhangsan用户下想cd ~,直接提示No such file or directory,用su - zhangsan也会因为没有可用的Shell而失败。
正确的做法是创建用户时把参数补齐:
bash复制useradd -m -s /bin/bash zhangsan
passwd zhangsan
其中-m表示自动创建家目录并复制默认配置文件(如.bashrc、.bash_profile),-s指定登录Shell。如果不确定之前有没有建过这个用户,可以先查一下:
bash复制id zhangsan
getent passwd zhangsan
这两个命令一个看UID和组信息,一个看用户在passwd文件里的记录,都能快速判断用户是否存在。另外还有个常见需求是批量新建用户,尤其是面试时偶尔会问到怎么批量创建10个用户。可以写个循环:
bash复制for i in $(seq 1 10); do
useradd -m -s /bin/bash user$i
echo "user$i:Passwd@123" | chpasswd
done
chpasswd可以从标准输入批量设置密码,比在循环里调passwd省事,而且不用交互。
2.2 删除文件夹命令,rm -rf 是核弹不是玩具
“linux删除文件夹命令”这个热搜词我太有感触了。新手最容易犯的错就是看到教程里写rm -rf就无脑用,完全不看路径,后果就是一条命令把系统重要目录干废。
在动手删东西之前,必须先明确几个基础概念,这也是我踩坑之后的总结:
rm file.txt:删除单个文件,会询问确认(取决于别名配置)。rm -r dir/:递归删除目录,包括里面的子目录和文件。rm -f:强制删除,不提示,文件不存在也不会报错。rm -rf dir/:递归且强制删除,不给任何确认机会。
说实话rm -rf不是不能用,但用之前一定要确认当前目录和绝对路径。我自己养成了一个习惯:删目录之前先执行pwd,再执行ls -la看一眼目录内容,尤其是以/开头的路径,看一遍再敲回车,心里踏实很多。
还有一个小技巧,在.bashrc里加一个别名做保护:
bash复制alias rm='rm -i'
这样普通rm命令会先询问确认,防止手快误删。不过要注意,-f仍然会绕过确认,别以为加了别名就万事大吉。
2.3 权限体系的速通模型:读、写、执行和所有者的关系
文件权限这块我一开始也绕晕过。-rw-r--r--这一串字符,正常人第一次看都懵。后来我用一个比较生活化的类比才彻底记住:权限就像一把钥匙,钥匙串上分明文(读)、可写(写)、可执行(执行)三把,每把钥匙还能复制给不同的人(所有者、所属组、其他人)。
具体来说,一条文件权限字符串分成四段:
| 位置 | 含义 | 示例 -rw-r--r-- |
|---|---|---|
| 第0位 | 文件类型 | - 普通文件,d 目录,l 软链接 |
| 第1~3位 | 所有者的权限 | rw-:可读可写不可执行 |
| 第4~6位 | 所属组的权限 | r--:只读 |
| 第7~9位 | 其他人的权限 | r--:只读 |
数字表达就更好记了:读是4,写是2,执行是1,加起来就是一组权限。比如chmod 755,7=4+2+1(所有者全权限),5=4+1(组和其他人可读可执行)。目录权限要注意,进入目录需要执行权限,所以目录一般至少是711,否则别人没法进入。
修改所属关系用chown,比如把目录交给某个用户:
bash复制chown -R zhangsan:zhangsan /data/app
-R递归处理子目录。很多部署问题到最后查出来都是权限不对,文件不是你的、目录你进不去,看着权限字符串发愁,其实把chown理清就好办。
3. 远程与传输:scp、find、sed 组合起来才算真会用
3.1 scp 命令:本地、服务器之间拷贝文件的最稳姿势
“linux scp命令”是高频搜索词,因为传文件几乎是日常必备场景。scp基于SSH协议,所以只要两台机器能SSH互通,scp就能用。我这边最常用的是三条:
bash复制# 本地文件推送到远程
scp /local/path/file.txt user@remote_host:/remote/path/
# 远程文件拉取到本地
scp user@remote_host:/remote/path/file.txt /local/path/
# 递归拷贝整个目录
scp -r /local/dir user@remote_host:/remote/path/
有几个易错点我遇到了好几次:
- 远程路径末尾的斜杠很重要。
/remote/path/表示拷贝到目录里,保持原文件名;/remote/path表示覆盖或重命名为path。我因为这个搞混过,结果把文件传成了别的名字。 - 端口不是默认22时用
-P参数,注意是大写P,和ssh -p的小写p不一样,容易记反。 - 传输大文件建议加
-C启用压缩,或者改用rsync支持断点续传。不过scp简单直接,临时传文件够用。
3.2 find 的用法:别只拿来按文件名找了
热搜词里的“linux find”和“linux find用法”,我结合自己的使用场景总结几个最有用的组合。
最基础的是按名字找:
bash复制find /etc -name "*.conf"
但find真正强大的是按时间、大小、类型、权限组合筛选。我举几个实际用过的例子:
bash复制# 找最近7天内修改过的文件
find /var/log -mtime -7 -type f
# 找大于500M的文件
find /data -size +500M -type f
# 找所有包含特定权限的可执行文件
find /usr/bin -perm /a+x -type f
# 找到并直接删除旧日志
find /var/log -name "*.log" -mtime +30 -exec rm {} \;
这里要特别解释一下-exec rm {} \;的写法:{}是find找到的每个文件名的占位符,\;表示命令结束。还有一个替代方案是用-delete参数,但-delete有些场景下会因为没有权限而报错,也需要小心在目录上递归删除的行为。
find配合xargs更常用,因为批量操作比逐条-exec效率高:
bash复制find /data -type f -name "*.tmp" -print0 | xargs -0 rm -f
-print0和-0配合,能正确处理文件名里带空格的情况,这是新手最容易忽略的细节。
3.3 sed 打印乱码:一个让我排查半天的问题
热搜词里有一条“linux sed 打印出来有乱码”,我一开始没明白为什么,后来自己遇到了才搞清楚。
场景是我想把一个配置文件里的注释行去掉,命令是:
bash复制sed -n '/^#/p' /etc/nginx/nginx.conf
结果终端里中文注释乱码。第一反应是编码问题,但查了文件明明是UTF-8。后来发现是我终端会话的LANG环境变量不对,SSH登录后LANG没有被正确继承,导致终端用错误的编码解析UTF-8字符。
排查命令如下:
bash复制echo $LANG
locale
如果输出是POSIX或者C,说明没设置UTF-8环境。临时解决:
bash复制export LANG=en_US.UTF-8
要永久生效就写进~/.bashrc。这个问题其实和sed本身没关系,但确实很容易被当成sed的锅。以后记住:终端显示中文乱码,先查locale,别急着怀疑命令。
另外sed还有一个容易被忽略的点:在macOS上使用sed -i和Linux不同,需要指定后缀,比如sed -i '' 's/old/new/g' file,否则会报错。写脚本的时候如果要在多个平台跑,这个差异必须注意。
4. 环境部署实录:docker 和 nginx 从安装到开机自启
4.1 linux安装docker:官方源下载慢的另一种解法
“linux安装docker”也是一个高频词,因为现在做开发很难避开容器化。官网给的安装方式很简单:
bash复制sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
但国内网络环境下,官方源下载速度很离谱,经常几KB/s。我最终采用的是阿里云镜像源,步骤如下:
bash复制sudo yum install -y yum-utils
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
装完之后启动服务:
bash复制sudo systemctl enable docker --now
这个命令是enable和--now的组合,等价于先systemctl enable docker再systemctl start docker,一步到位。验证是否安装成功:
bash复制docker version
docker run hello-world
docker run hello-world能拉取镜像并运行成功,就说明整个链路通了。如果只想把docker装上做个开发环境,到这一步已经够用。
4.2 docker镜像加速:pull慢的解决办法
安装docker之后第一件事就是配镜像加速器,否则拉取镜像一样要命。编辑/etc/docker/daemon.json:
json复制{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerproxy.com"
]
}
然后重启docker:
bash复制sudo systemctl daemon-reload
sudo systemctl restart docker
注意,如果daemon.json文件不存在,先创建一个再写入。配置镜像加速器之后,docker pull nginx这类操作会快很多。不过不同加速器的可用性会有变化,如果某个地址不可用,换一个即可。
4.3 linux安装nginx:从编译到直接干活
nginx安装方式有两种,一种是直接用包管理器:
bash复制sudo yum install nginx
这种方式简单,但很多时候安装的版本偏旧。另一种是编译安装,控制力更强。我这次用的是包管理器方式,重点放在配置上。
装完之后先启动:
bash复制sudo systemctl start nginx
sudo systemctl enable nginx
默认网站根目录在/usr/share/nginx/html,配置文件在/etc/nginx/nginx.conf。如果你想快速验证nginx是否正常工作,在浏览器访问服务器IP,看到Welcome页面就对了。
这里我要说一个运维中特别实用的操作:修改配置后先测试再重载。
bash复制nginx -t
sudo systemctl reload nginx
nginx -t会检查配置文件的语法和引用文件是否存在。很多人改了配置直接restart,万一配错了服务就挂了,而reload是平滑重载,如果测试不过就不会生效,线上环境非常好用。
4.4 开机自启与systemd:让服务在重启后自动恢复
docker和nginx装了之后,如果服务器重启,服务默认不会自己起来。解决办法是用systemd托管,上面已经用到了systemctl enable。这里再展开讲一下systemd的几个常用命令和服务管理思路:
| 场景 | 命令 |
|---|---|
| 查看服务状态 | systemctl status nginx |
| 设置开机自启 | systemctl enable nginx |
| 取消开机自启 | systemctl disable nginx |
| 立即启动服务 | systemctl start nginx |
| 重启服务 | systemctl restart nginx |
| 平滑重载配置 | systemctl reload nginx |
reload和restart的区别值得多说两句。restart是先把进程杀掉再重新拉起,会有短暂的服务中断;reload是让正在运行的进程重新读配置,对nginx这类支持优雅重载的服务来说,完全不会中断请求。所以生产环境能用reload解决的问题,尽量别用restart。
对于我们自己打包的二进制服务,也可以用systemd写Unit文件托管,比如:
ini复制[Unit]
Description=My Custom Service
After=network.target
[Service]
Type=simple
User=zhangsan
WorkingDirectory=/data/app
ExecStart=/data/app/myapp
Restart=on-failure
[Install]
WantedBy=multi-user.target
放到/etc/systemd/system/myapp.service,然后执行systemctl daemon-reload,就能像管理nginx一样管理自定义服务了。这一步学明白之后,部署任何脚本或程序都用得上。
5. 系统排查三板斧:端口、进程、资源占用一次说清
5.1 端口占用:9090端口到底是谁在用
热搜词里有一条“linux的9090端口什么再用”,这种问题几乎每个接触服务器的人都遇到过。排查端口占用的命令,我现在已经形成肌肉记忆了:
bash复制netstat -tlnp | grep 9090
或者用更新的ss命令:
bash复制ss -tlnp | grep 9090
两个命令的输出类似,能看到端口对应的进程PID和程序名。如果提示权限不够看不到PID,加sudo。
还有一个更精细的查询方式是用lsof:
bash复制lsof -i :9090
这个命令能显示占用该端口的进程、用户、文件描述符等信息,排查时非常直观。有时候端口明明没被监听,但你访问不通,那就要检查防火墙:
bash复制sudo firewall-cmd --list-ports
sudo firewall-cmd --zone=public --add-port=9090/tcp --permanent
sudo firewall-cmd --reload
这个流程走一遍,端口问题基本都能定位。
5.2 查看GPU显卡cache版本:一个容易混淆的查询场景
热搜词里有“linux查看cache版本”,我推测实际可能是想查显卡或者CPU的缓存信息。这种模糊搜索词在初学者里很常见,我顺着这个思路把相关命令整理一下,方便大家查的时候不迷糊。
查CPU缓存:
bash复制lscpu | grep -i cache
查内存信息:
bash复制free -h
查磁盘剩余:
bash复制df -h
查显卡型号和驱动:
bash复制lspci | grep -i vga
nvidia-smi
如果带NVIDIA显卡,nvidia-smi能显示驱动版本、显存占用、GPU利用率,这个查“cache版本”的关键词虽然不精确,但往硬件信息方向查就对了。真正要说缓存,Linux系统里还有一级二级三级CPU缓存,lscpu都看得清清楚楚。
5.3 系统资源占用:top和free怎么看才不白看
遇到系统卡顿,很多人第一反应是执行top,但看到一堆数字又不知道重点在哪。我分享一下自己的判断顺序:
- 看第一行
load average,这是1分钟、5分钟、15分钟的平均负载。如果三个数都高于CPU核数,说明系统很忙。 - 看
%Cpu(s),重点看us(用户态)和wa(I/O等待),wa高通常是磁盘太慢或者在做大量磁盘读写。 - 看进程列表里
%MEM最高的进程,通常就是内存大户。 - 按
P键按CPU排序,按M键按内存排序,快速定位问题进程。
查看内存使用细节用free -h,关注available这一列,这是真正可用的内存,比used更有参考价值。还有一个不太常用的vmstat:
bash复制vmstat 1 5
每秒输出一次,共5次,能看r(运行队列)、b(阻塞进程)、si/so(交换分区写入读入),对判断内存和CPU压力很有帮助。
5.4 网络排查:ping和telnet的边界
网络问题排查时,我经常遇到有人一上来就ping目标地址,ping不通就认为是网络故障。实际上ping走的是ICMP协议,很多服务器默认禁ping,ping不通不代表TCP端口不通。正确的排查顺序应该是:
bash复制# 先看本机网卡和IP
ip addr
# 看路由是否正常
ip route
# 测DNS解析
getent hosts example.com
# 测TCP端口是否通
telnet example.com 80
telnet能连上就说明端口通,连不上再看是不是防火墙拦截、服务没启动、或者IP根本不对。热搜词里提到的“linux的9090端口什么再用”本质也是这个排查链路的一部分:先确定端口有没有监听,再确认防火墙放没放行,最后从外部连接测试,这样才能判断问题出在哪一环。
6. 面试题之外:linux学习进度怎么自我检验
6.1 常见面试题的重复模式
“linux面试题测试”这个热搜词说明很多人学Linux的动机里有求职成分。我看了一些题之后发现,面试题翻来覆去问的就那几个方向:
- 查看进程、杀掉进程:
ps aux、kill、kill -9 - 查看端口:
netstat、ss - 文件权限:
chmod、chown - 文本处理:
grep、sed、awk - 软链接硬链接区别
- 查找文件:
find - 统计行数、去重:
wc -l、sort | uniq -c - crontab定时任务
- 系统负载排查
这些题目本身不难,但面试官很喜欢追问“为什么”。比如会问:为什么kill -9要慎用?答案不是“因为会强制杀掉进程”这么简单,而是kill -9直接让内核终止进程,进程没机会清理临时文件、释放锁、关闭连接,可能导致数据损坏或端口残留。
这种“知道命令是什么,还要知道为什么”的思维方式,才是面试和实际工作中的分水岭。
6.2 用真实场景自测:把命令串起来
刷题和真正解决问题是两回事。我给自己设计了一个自测小场景,这里分享给大家,可以用来检验自己的Linux掌握程度。
假设这样一个需求:找到/data/logs目录下7天前修改过的所有.log文件,按文件大小排序,统计总大小,然后把最大的前5个文件压缩备份到/backup。
我的做法:
bash复制# 找到7天前的log文件
find /data/logs -name "*.log" -mtime +7 -type f > /tmp/old_logs.txt
# 按大小排序,取前5
cat /tmp/old_logs.txt | xargs ls -lhS | head -6
# 全部打包
tar -czf /backup/old_logs_$(date +%Y%m%d).tar.gz -T /tmp/old_logs.txt
这个串联里涉及find、xargs、sort(隐含在ls -S中)、管道、变量、date命令,基本覆盖了日常命令的八成场景。如果你能不看答案独立写出来,说明这一阶段的学习效果是达标的。
6.3 学习中期的常见误区整理
这个阶段我复盘了一下自己的学习过程,有几个典型的误区,写出来帮大家避雷:
误区一:背命令但不理解参数。 比如背了rm -rf,但不清楚-r是递归、-f是强制,出了问题不知道怎么调整。
误区二:只在教程环境里练习。 教程环境通常路径简单、用户权限充足,和真实服务器差别很大。建议自己装个虚拟机或者用云服务器,模拟真实的部署、权限、网络环境。
误区三:出了问题直接复制网上的命令。 这不能完全避免,但至少要在执行前看懂每条命令在干什么。尤其是带rm、dd、mkfs这些危险操作的命令,不明确后果就不要执行。
误区四:不会看帮助文档。 man ls、ls --help、tldr ls 这几个命令能解决大部分参数疑问,比上网搜索快得多。学Linux最核心的能力就是自己查文档。
6.4 输出倒逼输入:我为什么开始记录进度
最后聊一下我为什么要整理这份学习进度记录。其实不只是为了给自己看,也是因为输出是最好的检验方式。
当你想把一个命令、一个配置、一个排查流程讲清楚的时候,你才会发现自己哪里是“知道”哪里是“真懂”。比如我之前觉得自己会用sed,但真要把“为什么sed -n '/^#/p'只会打印以#开头的行”讲明白,就得去搞清楚-n的作用、p的作用、正则的定位方式,这一下就深了很多。
所以我建议各位也尝试用这种“项目进度记录”的方式学习,每学一个模块就写一篇总结,不用多专业,关键是把命令、原因、坑点写清楚。过一段时间回看,能明显感觉到自己的进步,而且这份记录本身也是面试时可以拿出来讲的实战素材。
我第二期的学习进度大概就是这样,从账号权限到远程传输,从服务部署到系统排查,再到最后的面试自测,算是一个比较完整的闭环。下一步我准备往shell脚本编程和网络协议方向深入,等有新的积累再来更新第三期。
