
今天是Linux学习第八天。前面的基础命令、文件操作、文本处理已经过完一遍vim也算勉强能用了这一天的内容明显带有一点“从会用走向懂一点原理”的味道。我把今天的学习过程完整梳理一遍重点记录四个方面用户与权限管理、文件系统与磁盘操作、进程管理与系统监控、网络配置与共享上网最后再附上几个真实踩坑的故障排查过程给和我一样在自学Linux的人一些参考。1. 用户与权限管理实战1.1 从新建用户开始理解系统多用户模型第七天之前我对用户的概念还停留在“root和普通用户”这个层面上第八天真正开始动手创建和管理用户。创建用户用到的核心命令是useradd这个工具的命令行参数非常多但实际高频使用的其实就那么几个组合。最基础的一个添加用户示例useradd -m -s /bin/bash -d /home/zhangsan -G wheel zhangsan参数含义很直白-m表示自动创建家目录-s指定登录shell-d指定家目录路径-G把用户加入附加组。为什么需要一个附加组这就要谈到Linux默认没有独立的用户组概念而是采用“组”来管理权限集合。把用户加入wheel组后续就可以通过sudo规则允许这个用户执行管理命令这比直接给root权限要安全得多。再看用户信息到底存放在哪里。用户记录写进了/etc/passwd、/etc/shadow、/etc/group这几个文件。认识这些文件的结构比死记命令重要得多比如/etc/passwd中一行记录有七个字段用冒号分隔依次是用户名、密码占位符、UID、GID、用户描述、家目录、登录shell。创建用户之后我特意用cat查看了这几行的具体变化cat /etc/passwd | grep zhangsan cat /etc/shadow | grep zhangsan返回的内容里能看到zhangsan:x:1001:1001::/home/zhangsan:/bin/bash这就算是把用户创建的底账搞清楚了以后排查问题时思路会宽很多。设置密码使用passwd zhangsan交互式输入两次即可。passwd还有一个隐藏用法就是锁定和解锁账户这在团队协作或临时下线人员时非常实用对应的参数是-l和-u。删除用户用userdel -r zhangsan-r参数会连带删除家目录和邮件池如果不加这个参数用户虽然删掉了但文件还在系统里容易留下一堆“垃圾资产”。1.2 权限模型与安全底线用户管理必须配合权限控制才有意义。Linux的权限模型是“读r、写w、执行x”三组分别作用于属主、属组、其他用户。数字表示法中r4、w2、x1把三者相加就可得到一个组的值比如7表示rwx5表示r-x3表示wx。这套模型几乎渗透到系统的每个角落所以第八天的重点就是反复操作chmod、chown、chgrp。有一次我在服务器上用chmod -R 777 /var/lib/mysql给某个应用目录“放开权限”结果格式化输出立马出现了各种不可预期的问题因为mysql对目录权限有校验777反而会触发告警。这也是我第八天最大的心得之一权限不是越大越好而是“最小够用原则”。合理的权限规划一般是这样场景建议权限说明普通文件644属主可读写组和其他可读可执行文件755属主可读写执行其他可读执行私密配置文件600仅属主可读写脚本目录750属主可读写执行组可读执行chown用于修改文件归属比如chown zhangsan:devops /data/app表示把文件属主改为zhangsan、属组改为devops。许多新手会在需要root权限时直接改属主为root这有时是合理的但更要考虑是否真的需要因为属主为root意味着普通用户无法写反而能起到保护作用。1.3 提权机制的正确理解“提权”在系统管理中是一个中性概念核心就是让普通用户在需要时临时获得root权限。sudo是Linux下最常用的提权工具它并不直接给用户root密码而是通过/etc/sudoers文件定义规则。这个文件必须用visudo命令编辑因为visudo自带语法检查能防止写错规则导致sudo直接不可用。我一开始的理解是sudo 万能后来发现sudo的精髓其实是“精确授权”。比如允许zhangsan只执行systemctl restart nginx不给他完整的shell权限配置如下zhangsan ALL(ALL) /usr/bin/systemctl restart nginx这样zhangsan能提权做的事情被限制在一两个命令上即使账户被攻破损害范围也有限。sudo -l命令可以查看当前用户被授予的权限列表这是我在配置完规则后第一时间验证的方式。与此同时还有一个门槛比较高的机制是SETUID位也就是s权限。常见的/usr/bin/passwd就带这种权限普通用户运行它时临时获得文件属主的权限。这个机制如果使用不当就是系统安全上最容易出洞的地方。我特意用find / -perm -4000 -type f命令找了一下系统里有哪些文件带SUID位结果看到了ping、mount、su这些逐一核对了用途。在学习阶段一定要建立这个概念不能让非可信的二进制文件带SUID位否则一旦程序有漏洞整个系统就危险了。2. 文件系统、磁盘操作与存储挂载2.1 删除操作的安全意识第八天开始大量接触磁盘、分区、挂载相关命令也就无可避免地要处理删除操作。rm命令大家都会但真正让我警惕的是rm -rf这个组合。之前我听说有人把rm -rf /usr/写错直接把系统库文件删了个底朝天导致系统直接报废。这个教训放在任何一台生产服务器上都是灾难级别的。按我现在的习惯删除之前一定会先确认三个问题删除的是什么路径当前路径是哪里有没有备份特别是先执行cd /和pwd确认目录再使用ls查看待删除内容最后才执行rm。如果是在脚本中做删除动作我建议在命令中强制加上路径判断或者用find加条件删除避免写成裸的rm -rf $DIR这种不可控的写法。# 一种相对安全的写法先判断目录存在再删除 if [ -d /data/old_backup ]; then rm -rf /data/old_backup fi每次在删除前多花几十秒确认可能就避免了一次无法挽回的事故。2.2 挂载与存储从U盘到NAS挂载是Linux文件系统里一个很核心的概念。理解挂载的钥匙是Linux中一切设备都要通过挂载点才能访问这个挂载点就是一个目录。比如插上U盘后它对应的设备文件可能是/dev/sdb1但你不能直接读/dev/sdb1需要把它挂到一个目录下才能像文件一样浏览。基础挂载命令mkdir -p /mnt/usb mount /dev/sdb1 /mnt/usb df -hdf -h查看挂载后的容量和使用率。第八天不仅仅是格式化U盘这种入门操作我特意模拟了一个挂载NAS存储的场景。NAS存储最常见的网络文件协议是NFS挂载NFS之后远程存储的目录就能像本地目录一样读写。NFS挂载的步骤并不难先确认服务端导出了哪些路径然后mount -t nfs 192.168.1.100:/data/share /mnt/nas-data之后用df -h看结果。但是有个非常常见的坑NFS版本不兼容或缺少nfs-utils包会直接报错mount.nfs: No such device这通常不是网络问题而是客户端根本没装NFS支持组件。我在CentOS和Ubuntu上都遇到过解决办法就是先安装nfs-common或者nfs-utils包。对于生产环境开机自动挂载一般要写进/etc/fstab。fstab格式里的字段依次是设备标识、挂载点、文件系统类型、挂载参数、dump选项、fsck检查顺序。举个例子192.168.1.100:/data/share /mnt/nas-data nfs defaults,_netdev 0 0_netdev参数非常关键它告诉系统在网络就绪后再挂载否则开机时网络尚未启动挂载会失败并可能导致系统起不来。2.3 磁盘空间排查的实战思路排查磁盘占用是我目前工作中经常要做的事情。df -h看整体使用率du -sh *看当前目录下各子目录的大小这两个命令组合使用基本可以定位是什么文件把磁盘塞满了。但真正难缠的是另一种情况df显示磁盘满了但du统计出来却没那么大。后来学习了才明白这是因为某个进程打开了一个已删除但还未释放的文件空间被进程占用而非目录条目占用。排查这类问题的方法是用lsof L1列出已删除但仍在被进程占用的文件或者用lsof | grep deleted快速定位。找到是哪个进程占用后重启或杀掉该进程空间就会释放。这个坑在下次遇到时应优先想到而不是简单地把日志文件清空。另外根分区空间不足时有一个常见但不够安全的做法是直接删/var/log下的日志。合理做法是优先使用logrotate配置管理日志轮转限制日志文件数量和大小。至少也应该先用du -sh /var/log/*按目录看哪个占得多再做针对性清理而不是盲目删除。3. 进程管理与系统监控3.1 从ps/top到理解进程本质进程是Linux系统中另一个绕不开的核心概念。每天都要用到的ps aux看进程列表但真正理解进程状态是什么时候开始的第八天时我花了不少时间看top里的状态列R运行、S睡眠、D不可中断睡眠、Z僵尸、T停止。这些状态的切换直接反映了程序在干什么特别是僵尸进程父进程没调用wait回收子进程状态就会残留一个僵尸进程。僵尸本身不消耗CPU和内存但它是系统资源泄漏的信号长了很多说明父进程写得有问题。我做过一个实验写一个简单的shell脚本不断后台启动进程然后不等待很快ps里就出现一堆defunct解决方式是找到父进程PIDkill掉父进程僵尸就会被init进程回收。systemd提供给用户的日常操作核心是systemctl比如systemctl status nginx、systemctl restart nginx、systemctl enable nginx。相比传统SysVinitsystemd最大的好处是并行启动和按需启动服务间依赖关系由Unit定义。3.2 进程间通信与进程改名技巧进程间通信常在阅读后台服务代码时遇到。Linux下的IPC方式有不少管道、信号、共享内存、消息队列、Socket不同场景选择也不同。管道适合父子进程之间简单传递字节流共享内存适合高频大数据量交换但要处理同步问题Socket则能跨主机通信灵活性最高。学习阶段不用把每一种都用得很熟但至少要能在看到相关名词时知道它们解决的是进程间交互问题。还有个有意思的小技巧是修改进程名称。实际应用场景不少比如某个python脚本启动后在系统监控里显示的名字不直观或者想在前台进程名上标明当前运行环境就可以用修改进程名的方式让运维更容易识别。最直接的临时做法是在启动时用exec -a指定一个自定义名称exec -a my_custom_name python3 /data/worker.py在ps aux里看到的就是my_custom_name而不是python3了。如果是已经运行中的进程Linux的/proc文件系统提供了/proc/PID/comm和/proc/PID/cmdline某些情况下可以用prctl系统调用来实现进程内改名。对普通运维来说exec -a已经够用了。3.3 系统负载与性能分析初步top里右上角的load average虽然是老生常谈但正确解读它并不简单。三个数字分别表示1分钟、5分钟、15分钟的平均负载。初学者常犯的错误是认为负载超过1就有问题实际上负载是运行队列中的进程数要与CPU核数对比比如四核的机器load到4仍然正常超过核数才是排队。排查CPU占用过高的进程我习惯先用top按P排序再用ps -eo pid,ppid,cmd,%mem,%cpu --sort-%cpu | head看具体信息。而内存问题则不只看free -h的剩余内存还要关注cache部分因为Linux会尽量把空闲内存用作缓存以提高性能真正可用内存要看available列。如果发现某个可疑进程占用过高可以先用pidstat或者strace去观察它的系统调用确定它在做什么操作再决定是否重启或杀掉。这个排查思路能避免误杀正常服务。4. 网络配置与共享上网4.1 网络配置的两个派系网络配置是Linux学习里比较让人头疼的部分因为旧时代是ifconfig和/etc/sysconfig/network-scripts/ifcfg-eth0现在主流发行版都在转向NetworkManager和ip命令。如果还习惯性用ifconfig可能在较新的系统上看到command not found这是因为net-tools包没装。ip命令是现代的标配查看网卡信息用ip addr show查看路由用ip route。改IP地址时Rocky Linux 10这类新版本大量使用nmcli工具来管理网络。通过nmcli命令修改连接配置nmcli connection modify ens160 ipv4.addresses 192.168.1.10/24 nmcli connection modify ens160 ipv4.gateway 192.168.1.1 nmcli connection modify ens160 ipv4.dns 223.5.5.5 8.8.4.4 nmcli connection modify ens160 ipv4.method manual nmcli connection up ens160这套方式在所有支持NetworkManager的系统上基本统一。修改网络配置后一定要测试连通性ping网关、ping外网再nslookup域名确认DNS也通。网络配置改挂最怕的就是自己把自己锁在外面尤其远程连接服务器时建议改配置之前先写好改回原配置的预案或用screen保持一个原连接会话出问题还能抢救。4.2 搭建Linux共享上网网关局域网内多台设备通过一台Linux机器作为网关共享上网是网络实践里很经典的场景。其实背后的原理就是NAT把内网IP转换成出口公网IP。这里只讲技术原理和常规配置。第一台Linux主机连接外网网卡是ens160连接内网的网卡是ens192然后开启内核转发echo net.ipv4.ip_forward 1 /etc/sysctl.conf sysctl -p再使用iptables配置NAT转发规则iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o ens160 -j MASQUERADE内网设备把网关指向这台Linux主机DNS也设置成这台主机或公共DNS就可以访问外部网络了。这个过程理解SNAT和DNAT的区别是关键SNAT修改的是源地址适用于内网访问外网DNAT修改的是目的地址适用于端口转发。学习时动手搭一次之后再遇到企业里常见的上网行为管理、端口映射都是一条线上的事。4.3 常用网络故障排查命令排查网络问题最忌讳上来就重装网卡或重启网络我自己总结了一个低成本的排查顺序先看链路层再看到达性再看路由然后看DNS最后看防火墙。ip link show网卡是否up。ping网关二层三层有没有通。ping外部IP路由和NAT是否正常。nslookup域名DNS解析是否正常。ss -tlnp监听端口是否正常。这套顺序能快速把问题范围缩小到是网络配置、路由还是服务本身。比如有时候服务起不来但提示端口被占用用ss -tlnp看监听进程一眼就明白了完全不需要重启机器。5. 脚本化操作与自动化5.1 shell脚本的基本骨架天天手动敲命令效率太低第八天开始认真写shell脚本。一个规范的shell脚本开头先声明解析器然后设置严格模式#!/bin/bash set -euo pipefail这行可以说是新手最容易忽略但价值最大的配置。set -e让脚本在遇到错误时立即退出set -u防止使用未定义变量set -o pipefail让管道中任何一环失败都导致整个管道失败。没有这行配置脚本经常在出错后继续执行造成更复杂的问题。之后是变量定义、函数定义、主要业务逻辑。下面分享一个我练习时写的目录备份示例脚本#!/bin/bash set -euo pipefail BACKUP_DIR/data/backup SOURCE_DIR/data/www DATE$(date %Y%m%d_%H%M%S) TAR_FILE${BACKUP_DIR}/www_${DATE}.tar.gz mkdir -p ${BACKUP_DIR} tar -czf ${TAR_FILE} ${SOURCE_DIR} # 清理7天以前的备份 find ${BACKUP_DIR} -name *.tar.gz -mtime 7 -delete echo 备份完成: ${TAR_FILE}tar打包、find清理旧备份加上一点时间戳变量就能完成一个比较安全的自动化任务。脚本中用引号包裹变量是必须做的习惯否则路径含空格时会出现无法预料的拆分成多个参数。5.2 cron定时任务的实际使用自动化任务离不开cron。crontab -e编辑当前用户的定时任务crontab -l查看已有任务。cron表达式五个字段分别是分、时、日、月、周我用一个保存网站备份的定时任务做例子30 2 * * * /data/scripts/backup.sh /var/log/backup.log 21表示每天凌晨2点30分执行备份脚本并把标准输出和错误都重定向到日志。重定向这个细节看起来不起眼但没有它定时任务出错时根本无从排查因为cron的报错只会在系统邮箱里大多数日常工作场景没有人看linux mail。脚本执行权限要记得设置chmod x如果是root的crontab里执行非root用户的脚本还要注意脚本内可能需要指定用户身份可以用sudo或者直接在脚本开头加判断。5.3 常用命令的整理与自建手册学习Linux时信息过载很常见。命令多到记不住是自然现象我的做法是用一个markdown文件维护自己的命令备忘按功能分目录记录每周回顾一次。比如网络类、磁盘类、权限类分开同时记录遇到的坑和对应的临时解决命令。这种方法比直接存书签或收藏一个网页强得多因为写一遍等于加深一遍记忆而且记录的是自己真实踩过的坑下次复用价值高。推荐每个学习者都整理一份这样的个人速查表比任何“Linux命令大全手册”都更适合自己。6. 故障排查与踩坑实录6.1 误删系统库的真实经历我实际遇到过因为误执行删除命令导致系统大面积异常的情况。一次是清理临时文件时把/usr/lib/python3/dist-packages里的部分文件给删了当时就没有意识到这会破坏系统的Python环境。结果很多依赖Python的系统工具都坏了包括部分安装器。修复思路只能是重装系统组件从软件源重新安装Python相关包。这个经历让我切身体会到系统库目录不是随便就能删的清理路径前必须确认是否属于软件包管理的范围。排查时可以先用rpm -qf或者dpkg -S检查文件属于哪个包再决定是否删除。以CentOS为例rpm -qf /usr/lib/python3/dist-packages/somefile如果结果显示属于某个具体的软件包那就说明这个文件是受包管理器管制的不能随意删除。修复时直接重装对应包即可。6.2 开机卡在emergency mode的处理还有一次修改/etc/fstab写错了挂载参数重启后系统直接进入emergency mode。那一次是典型的“配置改动导致无法正常启动”我记得终端直接显示“Welcome to emergency mode”提示。处理步骤是输入root密码登录先查看挂载状态再检查fstab把有问题的行注释掉然后重新挂载或者改正参数最后重启验证。这种问题在虚拟机上还能通过快照回滚在物理机上就只能用单用户模式修复。所以学习阶段操作fstab一定要慎之又慎。每次修改fstab前最少先备份一份原文件cp /etc/fstab /etc/fstab.bak这样即使改出问题也能很快恢复。6.3 故障排查速查表结合这段时间踩过的坑我整理了一份适合初学者使用的排查速查表故障现象排查命令常见原因磁盘空间满df -h, du -sh *大日志文件、未释放的已删文件端口被占用ss -tlnp, lsof -i:端口服务重复启动、残留进程系统负载高top, pidstatCPU密集任务、死循环、频繁中断网络不通ip addr, ping, routeIP配置错误、路由缺失、网卡down命令找不到which, type环境变量PATH不对、软件没装无法ssh登录ss -tlnp, journalctl -u sshdsshd没启动、防火墙挡了、IP限制用户无法sudosudo -l, /etc/sudoers用户不在sudo组、规则写错挂载失败dmesg, mount, blkid设备不存在、文件系统类型错误、未安装客户端包排查任何故障第一件事都是先确认“最近改了什么配置”这句话往往比任何命令都管用。很多系统问题的根源都来自刚改过的配置而用户已经忘记了自己改过什么。第八天把用户、权限、文件系统、进程、网络、脚本、故障排查完整过了一遍信息量比前几天都要大。对我个人来说收获最大的不是单纯的命令记忆而是意识到系统管理本质上是在“路径和权限”上做文章一切操作都要尊重文件系统结构、权限边界和配置文件的语法。有个习惯建议坚持下来每做完一个练习就完整记录操作过程和结果哪怕只是几行笔记。过两个月再回头看这份记录会比很多视频教程更有价值因为它是你自己真实的操作路径。如果把我这个第八天的节点做一个总结我会说基础已经不算小白了但从基础到熟练中间还差着反复练习和大量排错的距离这个过程急不来。