Linux自学第14天:从命令行到系统管理与排障实战
发布时间:2026/10/6 13:51:45 作者:尧图编辑部 阅读量:1,286

自学linux第十四天我明显感觉到自己已经从“照着教程敲命令”过渡到了“能用命令行主动思考问题”的阶段。这两周下来常用的linux命令、系统管理、shell脚本这些东西拼成了一个越来越完整的拼图。十四天是个很微妙的时间点基础命令不再陌生系统安装也踩过坑开始对进程、权限、日志这些概念有了体感同时也第一次意识到光会敲命令远远不够得开始往深层原理走。这篇文章就记录一下第十四周期的学习内容——用户与进程管理、shell自动化、软件与镜像源、故障排查以及我第一次对linux底层原理有了自己的理解框架。1. 从命令行到系统管理今天开始对“用户”和“进程”有感觉了1.1 用户与权限让多用户操作系统真正“多用户”前十三天我其实一直在“单人单机”的视角下用linux无非就是cd、ls、grep、vim这些操作。但linux本质是多用户操作系统第十四天我终于把用户管理和权限体系系统地过了一遍。先说用户管理。Linux下的用户不是“注册账号”那种概念而是系统用来控制资源归属和权限边界的基础单位。最常用的几条命令useradd -m -s /bin/bash username创建用户-m自动创建家目录passwd username设置或者修改密码usermod -aG sudo username把用户加入sudo组userdel -r username删除用户并清理家目录这里有个新手特别容易踩的坑useradd在有些发行版上默认不创建家目录如果不加-m新用户登录后会直接落在/下后面各种配置文件就只能手动建特别别扭。我在虚拟机里试过一次没加-m结果用户连.bashrc都没有登录提示符都怪怪的。所以现在只要建用户我默认一定带-m和-s两个参数确保家目录存在、shell是bash。用户信息分布在三个文件里/etc/passwd存用户基本信息/etc/shadow存密码哈希和有效期/etc/group存用户组。理解这三个文件之后就明白为什么改密码要用passwd而不是直接编辑/etc/shadow——后者需要处理hash算法和锁文件手改很容易把自己锁在系统外面。然后是权限。ls -l输出的那一串-rw-r--r--第一位是文件类型后面三组分别是属主、属组、其他人的权限。chmod有两种玩法数字法chmod 750 filer4、w2、x1加起来。7rwx5r-x0---。符号法chmod ux file、chmod g-w file对单个人群调整。我的习惯是需要精确设置时用数字法因为“一眼能看出最终权限”临时调整时用符号法因为不用心算。另外chown user:group file用来改属主属组部署服务的时候特别常见。还有一个容易忽略的umask。它是“默认权限掩码”直接决定新建文件的默认权限。系统默认022所以普通文件是644、目录是755。如果你在部署Web服务时希望新文件默认对组可写就得调整umask。这个点面试也常考我后面在第五部分会再提。1.2 进程管理掌控后台而不是被进程拖着走系统管理绕不开进程。第十四天我把进程相关的命令串了一遍发现以前只是会ps aux看一眼现在才真正理解什么是“进程状态”。ps aux看全量进程快照top看动态刷新。不过我更推荐htop颜色、树状结构、直接按F9杀进程信息密度比top高很多。学习阶段没必要用top硬扛工具是拿来用的。进程状态里有个概念特别关键僵尸进程。它是子进程退出后父进程没调用wait()回收进程表里残留的“尸体”。在ps输出里显示为Z状态。怎么处理杀父进程让init进程接管回收或者直接重启。理解了僵尸进程后面看内核的进程管理章节会轻松很多。发信号是控制进程的核心手段。kill -TERM 1234是礼貌地让进程处理收尾工作kill -KILL 1234是强制杀死。日常不用记一堆信号数字但1HUP、9KILL、15TERM最好记住。HUP信号非常实用很多服务比如nginxkill -HUP pid可以直接重载配置而不中断连接效果等同systemctl reload。修改进程名称这个热搜词让我挺意外但确实是个实用需求。你说的是ps里显示的进程名。如果你是启动一个shell脚本可以在脚本里用exec -a 新名字 命令来设置。比如写了一个检测脚本默认显示bash想让进程名更可读#!/bin/bash exec -a disk_check_worker sleep 3600如果是Python程序可以用setproctitle库import setproctitle setproctitle.setproctitle(data_collector_worker)这个东西在排查进程的时候很有价值——你一眼就能看出哪个进程是干什么的而不是十几个全是python3或bash。优先级调整也要提一下。nice -n -5 命令启动时调整renice -n -5 -p PID运行中调整。默认优先级是0负数需要root权限。不是说优先级越低越牛io密集和cpu密集的处理策略完全不同这个以后做性能调优会遇到。2. Shell脚本第十四天开始让linux自动干活2.1 脚本骨架变量、判断、循环别把命令堆成一坨前十三天我都是手动执行各种linux常用命令。第十四天我终于开始认真写shell脚本目标是让重复性的操作自动化。先说一个核心体会脚本不是把命令一行行堆上去而是要有结构——变量、条件、循环、函数。先看一个我写的批量重命名脚本这个场景几乎人人都遇到过#!/bin/bash # 批量把当前目录下 .tmp 文件重命名为 .log for file in *.tmp; do [ -e $file ] || continue newname${file%.tmp}.log mv $file $newname echo renamed: $file - $newname done这里面有几处新手很容易写错for file in *.tmp如果当前目录没有匹配文件*.tmp这个模式会原样传给循环所以你需要在循环里加[ -e $file ] || continue做一个存在性判断避免对不存在的“字面量通配符”做mv操作。${file%.tmp}是bash的参数扩展意思是去掉结尾的.tmp。这个语法比sed处理文件名安全得多因为文件名的特殊字符不会干扰sed表达式。所有变量都要加双引号。如果不加文件名里有空格就会炸成多个参数。变量这块最核心的就是单引号和双引号的区别双引号里的变量会展开单引号里的就只是普通字符。写脚本时我默认全部用双引号包变量除非你真的想要字面量$符号。条件判断用if [ -f /etc/nginx/nginx.conf ]; then这种。[]里-f是判断文件是否存在且是普通文件-d判断目录-z判断字符串是否为空。这里有个经典陷阱[其实是个命令所以条件前后必须有空格。if[$a1]这种写法必挂而且报错非常不友好。循环里我比较爱用while read line处理文件逐行读取while IFS read -r line; do echo line: $line done access.logIFS表示不去除行首尾空格-r防止反斜杠被转义理解。这两个细节能避免很多脏数据问题。脚本开头我习惯写set -euo pipefail一行解决三个问题出错即退出、未定义变量报错、管道中任一命令失败都算失败。这个习惯是从运维老手那里学来的能让脚本在第一步出错时就停下来而不是带着错误状态往下跑最后产生更奇怪的结果。2.2 定时任务与自动化实战shell脚本最大的价值在配合定时任务。crontab -e编辑当前用户的计划任务crontab -l查看。cron的时间格式是五个字段分 时 日 月 周。比如每天凌晨2点半执行备份30 2 * * * /home/dev/backup_logs.sh /tmp/backup_cron.log 21注意几个cron的坑我全踩过环境变量问题。cron执行时不是登录shell很多PATH里的工具可能找不到脚本里尽量用绝对路径或者在脚本开头export PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。输出重定向。不加重定向的cron任务输出会通过mail发给用户最后堆积在/var/mail里。我习惯统一写 /tmp/xxx.log 21。脚本执行权限。cron直接执行脚本路径脚本需要chmod x或者cron里写成bash /home/dev/backup_logs.sh。一个比较完整的日志备份脚本大概长这样#!/bin/bash set -euo pipefail LOG_DIR/var/log/nginx BACKUP_DIR/data/backups DATE$(date %Y%m%d_%H%M%S) cd $BACKUP_DIR tar czf nginx_logs_$DATE.tar.gz -C /var/log nginx # 保留7天更早的删除 find $BACKUP_DIR -name nginx_logs_*.tar.gz -mtime 7 -deletefind配合-mtime 7删除历史备份这个组合是运维里最常用的清旧文件手段比手动看文件列表再删靠谱得多。-mtime 7的意思是修改时间大于7天注意是“n*24小时”如果某天备份时间不太固定边界会被跳过所以生产环境通常再留0.5天余量比如用-mtime 6。3. 软件部署与镜像源从“下载安装”到真正的环境治理3.1 包管理与换国内源第十四天系统学习后发现软件安装这件事不能只会一个apt install。先得理解包管理器的字面意思它管的是“包”之间的依赖关系。Debian系用apt配置文件主要在/etc/apt/sources.list。刚装完系统第一件事永远是换源。默认源在国外下载速度感人有些包还会反复失败。换成国内镜像之后体感从“一个gcc装半小时”变成“几十秒搞定”差距非常大。以Debian 13Trixie为例换清华源的操作是编辑/etc/apt/sources.listdeb http://mirrors.tuna.tsinghua.edu.cn/debian/ trixie main contrib non-free non-free-firmware然后apt update刷新索引。这里有个安全注意点源里的发行版代号必须和系统版本匹配。把stable的源用到trixie上apt会报错还会出现依赖解析混乱。我见过有人直接复制网上的源没看自己的版本号最后apt upgrade崩掉。比较常用的国内源清华 TUNAmirrors.tuna.tsinghua.edu.cn阿里云mirrors.aliyun.com中科大mirrors.ustc.edu.cn网易mirrors.163.com选择哪个都行关键是稳定性和更新频率。我自己的习惯是清华源放第一位置因为更新及时且支持https。3.2 编译安装与依赖地狱有些软件apt里没有或者版本太旧就得源码编译。这是我第一次认真对待configure make make install这条链。以编译安装gcc为例gcc依赖gmp、mpfr、mpc三个数学库这三个库又各自有依赖。此时最好的方案不是手动一个个编译而是用系统的包管理器先把基础依赖装好apt install -y libgmp-dev libmpfr-dev libmpc-dev然后是标准三步./configure --prefix/usr/local/gcc-13.2 make -j$(nproc) make install--prefix指定安装目录很关键。如果不指定默认装在/usr/local下文件会散落到bin、lib、share各个目录卸载和升级时根本理不干净。指定独立目录后想卸载直接删目录想切换版本改PATH就行。这是我从“到处装软件”到“环境治理”思维转变的重要一课。make -j$(nproc)里的$(nproc)表示用CPU核心数并行编译能大幅缩短编译时间。开太多并行会内存溢出一般2倍核心数以内都可以。实测在4核8G的机器上编译gcc用-j4大概二十多分钟-j1可能得一小时起差距非常明显。编译安装最常见的失败是缺头文件报错信息里“No such file or directory”这时不要盲目上网搜敲apt search 你缺的东西大概率是libxxx-dev这样的包没装。Debian系里-dev后缀就是开发头文件包。这条经验能解决80%的编译报错。3.3 MySQL、ClickHouse这类服务的安装要点软件部署不止是“装完能用”还得会初始化、会看服务状态。以MySQL 8.0.44为例我在另一台机器上完整走了一遍安装流程收获很大。二进制包方式的安装逻辑是通用的解压到/usr/local/mysql创建mysql用户初始化数据目录启动。初始化是新手最容错的一环老版本用mysqld --initialize会生成随机临时密码而且不同版本--initialize-insecure和--initialize生成的密码策略完全不同。我在测试机上用过--initialize-insecure也就是root初始为空密码然后立刻mysql_secure_installation强制设置密码、删除匿名用户。生产环境必须用--initialize拿临时密码这个别搞反。ClickHouse部署又是另一种风格。它提供了官方apt仓库装起来很顺apt install -y apt-transport-https ca-certificates curl gnupg curl -fsSL https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key | gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg echo deb [signed-by/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb stable main /etc/apt/sources.list.d/clickhouse.list apt update apt install -y clickhouse-server clickhouse-client安装完启动服务后用clickhouse-client连进去端口默认9000HTTP接口8123也可以curl访问。部署这类服务让我明白一件事每个软件都有自己推荐的安装路径不要用一个套路套所有软件先看官方文档的“Installation”一节是最高效的。至于Python的安装热词里也有“linux系统安装python”。我现在的做法是系统python保持不动用pyenv管理多个Python版本切版本、装依赖都不碰系统环境。编译Python之前记得先装libssl-dev libbz2-dev libreadline-dev libsqlite3-dev这一串依赖库否则装完的Python缺一堆标准库模块后面pip install各种报错。3.4 WSL子系统的两个坑有好几个人问到“Windows Linux更新子系统安装向导提前结束”的问题还有“虚拟机安装linux蓝屏”。这两个是最近的热门话题我也遇到过。WSL安装向导提前结束最常见原因是Windows功能里没有开启“虚拟机平台”。解决路径控制面板→程序→启用或关闭Windows功能→勾选“虚拟机平台”和“适用于Linux的Windows子系统”然后重启。另一个原因是主板BIOS的CPU虚拟化没开通常是Intel VT-x或AMD SVM需要在BIOS里开启。重启后重新运行向导基本就好了。虚拟机安装linux蓝屏大概率是VMware Workstation和Windows自带的Hyper-V冲突。新版VMware其实已经兼容Hyper-V但如果你的配置里同时启用了Hyper-V又跑老版本VMware崩溃概率极高。解决办法要么在“Windows功能”里关掉Hyper-V要么升级VMware到16/17新版本。还有一个玄学但实测有效的点虚拟机内存不要给太小2G以下装图形化linux时容易卡死蓝屏概率跟着涨。4. 故障排查实战第一次独立解决linux系统问题4.1 排查思路没有日志就别乱猜第十四天前后我把“linux运维故障案例”搜了个遍发现所有故障排查的正确姿势都一样先看日志再动手改东西。不基于日志的乱猜只会把问题改得更复杂。几个最重要的日志入口journalctl -xe查看systemd服务的最近错误信息-e直接跳到末尾journalctl -u nginx.service -f实时跟踪某个服务日志dmesg或者journalctl -k内核日志硬件、驱动、OOM这类问题在这看tail -f /var/log/syslog系统全局日志流我的排查套路一般是先systemctl status 服务名看服务状态和最近的日志不够细就journalctl -u 服务名 --since 10 minutes ago还是不行就grep -i error /var/log/xxx。三步下来80%的问题都能定位到具体报错。4.2 常见故障案例磁盘满、登录慢、服务起不来第一个案例磁盘满但不释放。典型现象是df -h显示根分区已经100%但你du -sh /一算文件总大小远小于占用。这时候十有八九是有进程占着已被删除的文件。清理命令lsof | grep deleted找到对应进程PID后重启进程或者kill -HUP PID让进程重新打开文件描述符空间就能释放。这个坑特别隐蔽我有次排查了一个多小时才意识到是日志文件被删了但进程没重启。第二个案例SSH登录很慢输密码要等好几秒。大概率是SSH默认开启了DNS反解和GSSAPIAuthentication。编辑/etc/ssh/sshd_configUseDNS no GSSAPIAuthentication no然后systemctl restart sshd速度立竿见影。这个案例我印象很深因为它根本不在“linux常用命令”范畴里而是要知道sshd的配置原理。第三个案例服务启动失败。systemctl status xxx只显示“failed to start”没有细节。这时候记得用journalctl -u xxx -n 50看完整日志。常见原因无非几个端口被占用、配置文件语法错误、权限不对。nginx的话先nginx -t测配置MySQL则是看/var/log/mysql/error.log。还有一个“删除文件夹命令”相关的话题。rm -rf是linux常用命令里最危险的一个我给自己定了一条规则rm -rf永远不用在变量不确定的路径上。比如rm -rf $DIR/*如果DIR为空这条命令会变成rm -rf /*后果没人想经历。替代方案是先把目录移动到/tmp下确认没问题再删或者用find ... -delete精确匹配。这不是小题大做生产环境的教训都是血泪换来的。4.3 安全与提权的自我修养“linux提权”这个话题在热搜词里很热。我理解这件事分两个层面一是合法管理场景下的权限调整二是安全视角下的防御认知。合法管理这一面就是su和sudo的使用。su是切换用户身份需要目标用户密码sudo是以其他身份执行命令只需要认证当前用户再配合/etc/sudoers里的授权规则。生产环境几乎只用sudo不暴露root密码。sudoers配置要谨慎给用户user ALL(ALL) ALL是给了这个用户所有root权限和把root密码给他没区别。安全防御这一面学习提权是为了知道攻击者是怎么进来的、能做什么然后反向加固。最常见的提权路径是应用服务以过高权限运行用户上传脚本后利用服务权限执行系统命令。所以正确的做法是用低权限用户跑nginx、php-fpm、tomcat这些服务目录属主和运行用户分开。我在部署服务时已经习惯先useradd -r 服务名建一个系统用户再用su -s /bin/bash 服务名确认权限边界。这个习惯能挡掉一大票默认配置里的安全风险也是面试中能加分的亮点。5. 从现象到本质开始理解Linux底层原理5.1 为什么第十四天该看内核了早几天看linux底层原理大概率是云里雾里连问题都提不出来。但到了第十四天掌握了一定量的命令和概念后再看原理就有了坐标感。至少你会好奇进程到底是怎么调度的df看到的文件系统和磁盘之间隔了几层ps为什么能拿到进程信息我给自己搭了一条理解链路命令 → 系统调用 → 内核子系统 → 硬件。比如你执行cat file它的路径是bash调用fork子进程调用execve加载cat程序cat调用open进入内核内核通过文件系统驱动去磁盘上找inode和数据块最后把内容读回用户态。理解了这条链很多零散知识就会挂到一棵树上。学习内核不一定要从源码啃起。我现在的路径是先看系统调用的表现用strace -c cat /etc/passwd可以统计一个命令用了哪些系统调用再针对高频系统调用去查《Linux内核设计与实现》里的对应章节。这种“从行为找原理”的方式比从开机启动开始读源码高效得多。5.2 进程间通信面试与工作中的重灾区linux进程间通信IPC是内核原理里最容易被问到的点也是我在第十四天重点梳理的内容。因为进程之间默认是隔离的要让它们协作必须借助内核提供的通信机制。梳理下来主要机制有这么几种机制特点典型场景管道pipe单向、基于文件描述符最轻量shell里的cmd1 | cmd2就是匿名管道命名管道FIFO有路径、可在无关进程间用简单场景的消息对传信号signal异步、开销最小只能传通知kill -HUP重载配置消息队列message queue有类型、有大小内核维护需要消息边界的短消息通信共享内存shm速度最快但需要同步机制配合高频大数据量传输信号量semaphore用于同步互斥而非传数据多进程操作同一资源套接字socket支持跨机器有TCP/UDP协议几乎所有网络服务工作中天天见的就是管道和socket。你写的grep管道就是一个匿名管道Redis、MySQL、Nginx这些服务进程间通信走的是socket本机的unix socket比TCP loopback更快所以本机部署时配置里都建议用/var/run/xxx.sock而不是127.0.0.1。一句话总结IPC面试知识管道轻量限血缘socket万能跨机器共享内存最快但你得自己操心同步信号量就是干同步这活的。能把这个说清楚这一块面试问题基本就稳了。5.3 面试题里的linux考察点热心词里反复出现“linux面试题”“linux常用命令大全运维”说明很多人自学的最终目的是通过面试。我在第十四天也扫了一些常见面试题发现它们考察的其实不是记忆而是对机制的理解。比如硬链接和软链接的区别。硬链接指向同一个inode删掉原文件链接还在数据不丢软链接是一个独立文件存着目标路径目标删了它就变成“断链”。运维里日志轮转就用软链接切换文件版本。再比如端口查看netstat -tlnp和ss -tlnp后者更快推荐直接用ss。ss -tlnp能看到端口归属进程排查端口被占用的效率最高。还有个点我印象很深父进程和孤儿进程。子进程被父进程启动父进程死了子进程会被init进程收养。但如果父进程活着却不回收已退出子进程就产生僵尸进程。运维排查时ps aux里看到一堆Z状态进程就知道要找父进程重启了。面试题本质上考的是你是否理解系统在做什么。所以我的建议是把“这个命令为什么会这样”当成学习主线。比如df显示的磁盘类型为什么和fdisk -l不完全一样free里的buff/cache是什么意思top的load average到底代表什么。这些问题搞懂一个比背十个命令有效。6. 第十四天的复盘与下一步规划6.1 这十四天我真正沉淀了什么回看这两周不短的自学路程我会把知识分成四层。第一层是“肌肉记忆层”就是linux常用命令包括cd、ls、grep、awk、sed、find、ps、ss、df、du这些它们不需要思考手到擒来。第二层是“运维操作层”包括用户权限管理、进程管理、日志查看、cron定时任务、软件安装和换源这些是系统管理员的日常。第三层是“故障排查层”基于日志定位问题比如磁盘空间不释放、服务起不来、SSH慢、WSL安装失败这一层经验越多自信越足。第四层是“原理理解层”开始懂系统调用、IPC、进程状态这些底层概念它让前面三层知识从碎片变成了体系。我特别推荐一种记录方式踩坑日志。每次报错都记一个条目包含错误信息、排查过程、最终原因。第十四天回看这些记录发现很多坑是重复出现的比如权限不足、依赖缺失、路径不对。如果早点记第二次遇到就能十分钟解决。6.2 给同样在自学的朋友的建议这十四天踩过的最大弯路是想把所有“linux常用命令大全”里的命令都背下来结果效率极低还容易忘。现在我的经验是常用命令先掌握30个重复使用到形成肌肉记忆遇到新需求时再去查文档查询一次、实践一次比背诵十次记忆更深刻。项目驱动是最好的自学方式。不要天天跟着教程敲“无意义”的命令而是给自己定一个目标搭一个个人网站写一个日志备份脚本部署一个MySQL加ClickHouse的数据统计环境。过程中所有命令都会用得顺理成章印象也最深。下一步我计划往三个方向深入第一把shell脚本从“能写”提升到“能写好”结构化、函数化、错误处理完备第二继续看《Linux内核设计与实现》重点读进程管理、内存管理和文件系统三章边看边用strace验证第三动手写一个监控脚本结合cron和shell监控磁盘、内存、关键服务到点发送告警。这个目标既能复用已学的知识又能逼自己探索新的内容。最后分享一个体感很深的经验linux自学的曲线不是一条直线而是阶梯形。前面十几天可能感觉进度很慢好像一直在敲命令、记参数但到了第十三四天这个节点很多概念突然开始串起来——进程、权限、日志、服务它们不是孤立的而是同一个系统不同侧面的表现。所以如果你也正好在坚持别急着比进度把每个命令背后的“为什么”弄明白到某个临界点你会明显感觉到视野突然开阔了。