带人这么多年我面试过不少自称“熟悉Linux”的候选人也带过刚入行的新人。说实话很多人是把命令背下来了但真扔到一台服务器前面让他查个问题、排查个故障手就僵住了。我常说一句话Linux不难但它有门槛这个门槛不是看你记住了多少条命令而是看你真正会用多少条。如果下面这些命令你只是“见过”或者“用过一两次”那真不能说会Linux。这篇文章不打算写成一本命令字典Linux命令上千条谁也不可能全背下来。我想换个角度从一个混了十年的老运维视角把那些“不会就等于不会Linux”的命令逐个过一遍告诉你它们真实的使用场景、常用的关键参数、以及我踩过的坑。你可以把这篇文章当成一张自测清单一条一条对照看看自己到底有没有真正掌握Linux的基本功。1. 先别急着背命令文件与目录操作才是地基很多人觉得文件操作就是cd、ls、rm太简单了没什么好学的。但恰恰是这些最基础的命令最能看出一个人对Linux的理解程度。我见过太多人在生产环境里执行rm -rf然后哭都来不及的场景也见过有人用find找文件能折腾一上午的。文件操作这块我的建议是基础命令要精通高级命令要熟练不要只会皮毛。1.1 cd、ls、rm不是入门三件套用好了是效率利器先说cd。这命令看起来没技术含量但“能不能快速到达目标目录”直接决定你的操作效率。我自己的习惯是绝对路径走天下相对路径只用在脚本里。曾经有个同事登录服务器后一直在路径之间来回跳跃用cd ../../..一层一层找看得我头皮发麻。后来我教他三个技巧第一用cd -在最近两个目录之间切换这个操作在排查问题时尤其好用第二用软链接把常用目录钉在固定位置比如ln -s /var/log/nginx /nginxlog以后直接cd /nginxlog第三配合tab补全输路径时按两下tab可以看到候选列表这比盲打强一百倍。ls的用法就更值得说说了。默认的ls输出信息太少很多新手根本不知道文件权限那串字符怎么看也不知道文件大小为什么不显示。我要求自己带的徒弟必须养成ls -lh的习惯h参数会自动把字节数转换成人类可读的K、M、G单位一眼就能看出哪个日志文件快把磁盘撑爆了。ls -lt按时间排序配合head使用快速找到最近修改的文件ls -la在排查隐藏文件时必不可少尤其是怀疑服务器被种了后门优先看有没有奇怪名称的隐藏文件。这些不是晦涩的冷门技巧而是每天都会用到的东西用什么顺序组合参数就是熟练度的体现。rm这个命令我说再多也不过分。第一原则是生产环境禁用rm能加引号就加引号能用find删除就find删除能先把目录改名观察再删就绝不做一锤子买卖。我有个习惯凡是要删重要目录先mv /data/app /data/app_bak_20250101观察三到七天没问题再清掉。这多花不了几分钟但能救你于水火。还有个细节rm -rf里的f参数是“强制”但很多人忽略了它同时也会抑制“不存在的文件”的报错提示导致你误以为自己删的是存在的目录。真正常见的做法是在脚本里这样写# 删除前先判断目录是否存在防止通配符展开错误 if [ -d /data/app_${DATE} ]; then rm -rf /data/app_${DATE} fi变量加双引号路径做存在性判断这两点哪怕只做到一个都能避免大部分rm事故。1.2 find和tar两个被严重低估的救命命令find是查找命令但它的能力远超“找文件”。我处理过最多的场景是磁盘空间告警这时候find就是第一把刀。比如find /data -type f -size 500M -exec ls -lh {} \;把大文件全部找出来再决定是清理还是归档。这里补充一个高频参数组合-mtime 30表示30天前修改过的文件配合日志清理需求极好用-name *.log限定文件类型-exec后面接处理动作可以执行任何你想执行的命令。但find有个大坑是通配符处理。如果你执行find /data -name *.log在某些shell环境下*.log可能被shell先展开再传给find一旦/data下正好有多个.log结尾的文件命令就会报“参数过多”的错误。正确写法是find /data -name *.log给文件名模式加上单引号让find自己处理通配符。这个细节面试的时候拿来考人一考一个准。tar的重要性不需要我强调但用法上很多人只停留在tar -zxvf。四个字母的排序其实暗含逻辑z是压缩方式x是解压v是显示过程f后面跟文件名f必须放在最后因为f需要接参数。我自己的习惯是打包时用tar -zcvf相当于“用gzip压缩、创建、显示过程、输出文件名”解压时用tar -zxvf。但你要记住不是所有tar包都是gzip压缩的.tar.bz2对应j参数.tar.xz对应J参数。盲目使用-zxvf解压其他压缩格式虽然tar有时能自动识别但遇到不兼容情况就会报错。如果实在记不住直接tar -xf 文件名.tar.gz现在新版本的tar能够自动识别大多数压缩格式少打几个参数反而更稳。2. 文本处理三剑客到底怎么用才算“会”Linux的一切皆文件而文件里装的最多的又是文本。日志分析、配置修改、数据提取这些活全落在grep、sed、awk这三兄弟身上。有人背了一大堆正则表达式真到实战却不知道从哪下手。我用十年经验浓缩成一句话grep用来找行sed用来改行awk用来取列三者的边界搞清楚就能解决九成问题。2.1 grep为什么是排查问题的第一选择grep几乎是我每天敲击次数最多的命令。它的核心能力就是从文本流中过滤出你想要的信息。最基础的用法是grep keyword 文件名但真正有用的场景是配合管道符使用例如cat /var/log/nginx/access.log | grep 500。注意管道符前可以接任何命令的输出这让你可以动态过滤实时信息比如ps aux | grep java。这里必须提一个坑岁数不小的坑用ps aux | grep java的时候如果Java进程不存在你依然会看到一条类似grep java的进程输出因为grep自己也会匹配到“java”这个关键词。这就是著名的“grep出自己”的坑。解决方案有两个一是加-v参数反向排除ps aux | grep -v grep | grep java更优雅的是用pgrep -f java或者ps aux | grep [j]ava用正则特性让grep匹配不到自身。grep参数中-i忽略大小写、-r递归搜索目录、-n显示行号、-c统计行数这四个是基础中的基础。再往上就是正则了^匹配行首$匹配行尾[]匹配字符集合.*任意字符\{n\}重复次数。我打一个形象的比方grep就好比在图书馆里找书正则就是你的检索规则规则越精准找到目标的速度越快。比如你要查IP地址是192.168开头且结尾是8080端口的日志行可以写grep ^192\.168\..*:8080 /var/log/app.log正则里的反斜杠转义点号是因为在正则里点号代表任意字符不转义就会把192x168也匹配出来。这类细节代码写得多了自然就体会到了。2.2 sed和awk一个用来改一个用来算sed是流编辑器擅长“读取文件-处理-输出”不改变原文件内容除非加上-i参数。我讲一个高频用法批量替换配置文件里的内容。比如要把nginx配置里所有8080端口改成9090端口一条命令搞定sed -i s/8080/9090/g /etc/nginx/nginx.confs就是substitution替换/8080/是要找的内容/9090/是替换成的内容g是全局替换不加的话每行只替换第一个匹配。/前面可以加行号或正则定位范围比如sed -i 10,20s/8080/9090/g表示只替换10到20行之间的内容。这比用vim手动改几千行的配置文件效率高太多。-i参数直接修改文件好使但没有后悔药。我的习惯是凡是动生产环境配置文件先sed s/8080/9090/g 原文件 新文件确认无误后再mv覆盖或者用sed -i.bak在修改前自动备份原文件。sed -i.bak的意思是修改的同时保留一份.bak后缀的备份这是很多老手在用的安全做法。awk的定位又不一样它长得像C语言但主要用来做文本处理和数据提取。最简单的例子awk {print $1}打印第一列$0表示整行NF表示列数NR表示行号。比如查看CPU使用率top -bn1 | grep Cpu | awk {print $8}这里的$8就是每列数据具体是哪个数要看top输出的格式这个需要自己核对文档。awk的处理逻辑是“按行为单位读入按列为单位切分”默认按空格/Tab切分指定分隔符用-F参数比如awk -F: {print $1} /etc/passwd以冒号分割提取用户名。但awk真正牛的地方在于统计和聚合。排查Nginx日志的时候我想看看哪些IP请求量最大一行awk搞定awk {count[$1]} END {for (ip in count) print ip, count[ip]} /var/log/nginx/access.log | sort -k2 -rn | head -20count[$1]是数组累加$1是IP列END块在所有行处理完之后执行遍历数组输出统计结果再用sort按第二列数值倒序排列。这已经算得上实打实的数据分析能力了堪比Excel里的透视表。3. 系统状态与网络排查不会看等于裸奔命令背得再熟服务器出问题你两眼一抹黑那就等于零。排查问题是有套路的首先看系统状态再看进程资源最后看网络链路。这一节我把几个核心命令的实战用法捋一遍。3.1 top命令详解除了CPU你还要看懂哪五列top命令可以说是运维的“仪表盘”服务器有没有问题、瓶颈在哪里基本扫一眼top就能有个结论。很多人看top只知道按大写P按CPU排序、按大写M按内存排序这算入门但远远不够。首先看第一行的load average后面有三个数字分别代表过去1分钟、5分钟、15分钟的系统负载平均值。这三个数字不是CPU使用率而是一个系统中处于可运行和不可中断状态的进程数的平均值。怎么判断负载高不高参考CPU核数比如4核机器负载4.0意味着每个核都满负荷负载8.0就是过载了。如果1分钟高、15分钟低说明是临时尖峰反过来1分钟低、15分钟高说明已经持续高负载一段时间需要警觉。再往下看进程列表重点关注的不是CPU那一列而要看进程的RES常驻内存和SHR共享内存判断进程真实占用内存。还要看进程状态列SR代表运行S代表睡眠D代表不可中断睡眠通常表示在等待IOZ代表僵尸进程。如果出现大量Z进程说明父进程没有正确回收子进程资源程序有bug或者被kill得不够干净需要排查。top的交互式快捷键也值得掌握按1显示每个CPU核的单独使用率按c显示完整命令行默认只显示进程名按h调出帮助菜单。我曾经遇到一个事故Java进程CPU飙到300%敲top一看进程名只显示java根本不知道是哪个服务按c键后看到完整命令行里带着特定的jar包路径立刻定位到问题服务。这些细节关键时候真的能救命。3.2 telnet能不能通网络链路排查三板斧网络排查这块telnet这个命令现在很多人不熟甚至觉得它老掉牙。但我负责任地说telnet ip port这个组合是测试TCP端口连通性最简便的方式没有之一。很多云厂商的安全组配置、防火墙规则是否正确用telnet一试便知。具体怎么用命令行输入telnet 192.168.1.10 3306如果端口开放会进入一个交互界面显示类似Connected to 192.168.1.10的提示如果不通会一直卡在Trying...然后超时或者直接报Connection refused。Connection refused和超时是两种截然不同的含义前者说明网络通则目标主机主动拒绝了请求往往是端口没监听或者防火墙拒绝后者说明数据包被丢弃了大概率是网络不通或安全组拦截。我见过不少新手看到Connection refused就以为网络不通其实恰恰相反能收到refused说明TCP握手已经到达了目标主机。但telnet也有自己的问题很多服务器为了安全并没有安装telnet客户端。这时候退而求其次用bash自带的/dev/tcp伪设备timeout 3 bash -c echo /dev/tcp/192.168.1.10/3306 echo port open || echo port closed/filtered这个命令的原理是利用bash的重定向功能向TCP套接字发起连接连接成功就echo通了失败则反馈错误。timeout 3表示最多等待3秒避免长时间卡住。链路排查三板斧我习惯的套路是先ping目标IP测ICMP通不通再telnet测试具体端口通不通如果通但业务异常就用ss或netstat查看端口监听状态和连接队列。ss命令是netstat的替代品性能好输出快查看监听端口用ss -lntp查看所有连接用ss -ant。排查网络问题最重要的心态是“分层定位”先分清是网络层、传输层还是应用层出问题再用对应的命令去验证。4. 软件部署与自动化管理从装系统到容器化的现代基本功看一个人是不是真正干过生产环境问问他怎么装软件、怎么管服务、怎么玩转容器基本就有数了。这一块知识更新快但核心思路没变把软件的安装、启动、更新、删除全部纳入可管理的轨道而不是像新手一样靠猜。4.1 软件包管理yum、apt、dnf背后的统一逻辑不同Linux发行版有不同的软件包管理工具CentOS/RHEL系用yum或dnfDebian/Ubuntu系用apt。但背后的逻辑是一致的软件仓库-依赖关系-元数据缓存-安装升级卸载。会了其中一个换到另一个发行版只需要一个小时就能上手。以CentOS系为例yum install -y nginx这里-y参数是在安装过程中自动回答yes避免交互式提示导致脚本卡住。升级软件用yum update 软件名如果直接执行yum update会把系统所有可更新软件包全部升级一遍。生产环境这么做要慎重因为某些软件升级后可能与现有配置不兼容尤其是内核版本升级需要明确知道自己在做什么。dnf是yum的下一代版本在RHEL 8及以后成为默认命令用法几乎一致。apt系的区别在于需要先apt update更新软件源索引再apt install -y 软件名。忘记执行apt update就去install经常会导致安装到旧版本甚至提示找不到软件包。还有一个三次被坑得记忆犹新的教训不要使用yum install去安装不属于官方源的软件包。很多第三方软件源配置不当会引入依赖冲突轻则软件运行不起来重则把系统的关键库给替换掉。我一朋友在测试环境配置了一个第三方源执行yum update后glibc被更新然后几乎所有的命令都开始报错最后只能重装系统。配置第三方源之前先问自己一句这个软件有没有官方源官方源有没有静态二进制包都不行的话宁可编译安装也别盲目添加第三方源。4.2 systemctl把服务生命周期掌握在自己手里十年前的Linux管理员用的是service命令和/etc/init.d目录下的脚本现在主流发行版全部切换到了systemd体系核心操作命令就是systemctl。最常用的几个子命令systemctl start 服务名启动、stop停止、restart重启、reload重载配置、enable设置开机自启、disable取消开机自启、status查看状态。但我见过很多人在使用systemctl时忽略了一个重要细节修改完服务的配置文件后必须执行systemctl daemon-reload让systemd重新读取配置然后才能用systemctl restart 服务名正常重启。如果跳过daemon-reloadsystemd可能还在按旧的配置运行。systemctl status 服务名这个命令信息量非常大。除了显示服务当前状态active running是正常failed是启动失败inactive dead是未运行还会显示主进程PID、最近几次日志记录以及关键的错误信息。排查服务为什么起不来第一条命令就应该是systemctl status它把90%的线索都摆在你面前了。如果服务启动失败想看完整日志用journalctl -u 服务名 -n 100查看最近100行加-f参数可以实时跟踪效果类似tail -f。4.3 git、docker与containerd现代Linux的核心素质现在的服务器环境没有git和docker寸步难行。git最基础的操作是git clone、git add、git commit、git push、git pull但我更想强调一个运维场景在服务器上更新代码。很多人喜欢直接在服务器上改代码这是极其不专业的做法。正确流程是本地改代码push到远程仓库服务器上git pull拉取更新。如果服务器上的代码与远程冲突优先用git status查看冲突文件用git diff确认改动差异再决定怎么解决。容器这一块docker和containerd的关系要搞清楚。docker是一个完整的容器管理工具containerd是底层的容器运行时docker本身也在用containerd来创建和管理容器。现在生产环境大量使用Kubernetes而K8s默认的运行时就是containerd。所以实际操作中你会发现服务器上既有docker命令又有crictl或ctr命令。docker常用命令docker ps查看运行中的容器docker ps -a查看所有容器包括已退出的docker images查看本地镜像docker exec -it 容器名 /bin/bash进入容器内部docker logs -f 容器名查看容器日志docker restart 容器名重启容器。如果是直接使用containerd的环境用crictl替代docker CLI命令风格类似crictl ps、crictl images、crictl exec -it 容器名 sh。这地方有个容易被新手忽略的坑容器内部安装的软件在容器重建后会全部丢失所以不要把容器当成虚拟机对待。配置文件要挂在外部存储数据要写在volume里日志要输出到标准输出由统一日志收集系统处理。我在生产环境看到过有人把数据库直接放在容器内部没有挂载外部磁盘结果容器一重启数据全没了那种绝望感我至今记忆犹新。5. 安全自查与提权防护守住系统的最后底线Linux安全这块最容易被忽视也最致命。很多人觉得服务器不出事就行但一旦出事就是大事。作为一个老运维我强烈建议每个管理员都定期做安全自查。这一节不讲攻击手法只讲自查思路和防御命令。5.1 权限与审计用最小权限原则自查你的系统Linux权限模型的核心就三点用户user、组group、其他人other以及读r4、写w2、执行x1三个权限位。权限值的计算很简单比如rwxr-xr-x对应755rw-r--r--对应644。但真正体现水平的是你会不会用特殊权限位setuids和setgids。setuid权限需要特别注意。一个可执行文件如果带setuid位那么任何用户执行它时进程的有效用户ID都是文件所有者典型的例子是/usr/bin/passwd。如果一个其他用户可写的文件被设置setuid且所有者是root那就是一个现成的提权漏洞。自检命令很简单# 找出系统中所有带setuid位的可执行文件 find / -perm -4000 -type f 2/dev/null同样的道理查看全局可写文件find / -perm -002 -type f 2/dev/null这些文件如果被恶意篡改后果不堪设想。我每个月巡检服务器的时候都会执行这两条命令对照文件列表新增的条目哪怕是可疑的都值得追查原因。sudo权限的管理也是安全重地。运行sudo -l查看当前用户有权限执行哪些命令如果输出显示类似(ALL) NOPASSWD: ALL那这个账号就等同于root必须严格保护。我还习惯定期检查/etc/sudoers文件重点关注有没有异常的命令授权比如某个普通用户被授权以root身份执行vim表面上看起来无害但vim可以打开任意文件甚至通过!命令执行shell这跟直接给root没有区别。5.2 应急响应思路服务器被入侵后的第一组命令安全话题绕不开应急响应。假设你发现服务器有异常比如CPU持续飙高、对外发送大量流量、出现不明进程时不要慌按照下面这个顺序执行命令# 第一查看当前登录的用户和登录来源 who w last # 第二查看系统所有用户的登录shell和UID cat /etc/passwd | awk -F: {print $1, $3, $7} | sort # 第三查看监听端口和对应进程 ss -antp # 第四检查进程树关注可疑进程路径 ps -ef pstree -a这套组合拳打下来大多数入侵的痕迹都会暴露。核心思路是“由外向内找线索”先看谁登录了系统再看系统里有什么异常账号然后看网络层有没有可疑监听最后看进程层有没有可疑程序。排查过程中切忌直接用kill杀死可疑进程。正确的做法是先用ls -l /proc/PID/exe查看这个进程的真实可执行文件路径再用cat /proc/PID/cmdline查看启动参数把这些信息保存下来再决定下一步。很多恶意程序会在被kill后自动重启清理源头才是解决问题的关键。我见过有人在应急响应时慌了神直接把怀疑是恶意的进程kill了结果权限反弹shell断了黑客立刻警觉并把服务器上的日志全部清空反而失去了所有可追踪的痕迹。网络安全不是黑客电影冷静、有序、保留证据才是正确态度。6. 十年经验浓缩的避坑清单帮你少走三年弯路最后这部分不讨论具体命令但我觉得比任何一条命令都重要。这些是十年摸爬滚打总结出来的心得分享给大家。第一不要在生产环境用root直接操作。能给你带来方便也能让你一个命令毁掉整个系统。平时用普通用户登录需要提权时用sudo每一步操作都有审计记录。作为运维被sudoers限制反而是一种保护。第二无论什么时候删除文件前先备份。哪怕是看着无关紧要的配置文件备份也能让你在出错时快速恢复现场。我的习惯是删除操作之前先把目标文件打包tar -czf config_$(date %Y%m%d).tar.gz /etc/nginx/后面再加成生成备份文件的日期回滚时一目了然。第三日志是你最好的朋友。服务器不会说话但它所有的行为都会记录在日志里。安装新软件后先确认日志文件位置排查问题时先看日志不要一头扎进配置文件里瞎猜。学会在/var/log目录下找到对应日志就迈过了新手和老手的分界线。第四也是最后一点持续学习比什么都重要。Linux每年的内核都在升级容器技术、自动化运维工具不断推陈出新没有一门技术学完就一劳永逸。但好消息是基础命令的底层逻辑几十年没变过掌握了文件、文本、权限、网络这些核心概念学什么新工具都只是换个壳子。我面试的时候经常问一个问题如果服务器突然ping不通了但你从云平台控制台能看到CPU占用100%你的排查思路是什么能答出用top看进程、用ss看连接、用journalctl看日志、再结合业务特征定位的人我一定会给过。因为这种思维才是Linux真正教会你的东西而不是那几十条命令的排列组合。