很多人学 Linux 常用命令的方式是先收藏一份几百条命令的清单然后从ls、cd开始背。背了两个星期以为自己会用 Linux 了结果真拿到一台出问题的机器反而不知道先敲哪条命令。我跟 Linux 打了十几年交道最想纠正的就是这个误区常用命令不是用来背的是用来“问”的。命令本身只是工具真正值钱的是你拿到一台陌生机器后能通过命令把它“问”清楚的能力。这篇文章不打算写成又一个“常用命令清单”而是按真实工作场景拆开讲讲文件操作、系统排障、权限控制、文本处理和网络诊断时那些命令组合起来该怎么用以及我踩过的一些坑。这回的内容适合刚接触 Linux 的初学者也适合那些能敲出ls和cd、但遇到问题依然无从下手的初级运维或后端开发。我会尽量把每条命令背后“为什么这么用”讲明白因为实际工作里命令记不记得住是其次能不能理解输出、能不能从报错里找到线索才是拉开差距的地方。1. 先放下“背命令”的执念学会让终端告诉你答案1.1 为什么命令清单总是看了就忘我见过很多人在笔记里保存过这样的命令tar -zxvf、chmod 777、kill -9。需要用的时候翻出来对着敲敲完也不知道发生了什么。这种学习方式的问题在于它把命令当成了“口诀”而不是把它当成“提问方式”。tar -zxvf是在问“这个压缩包里有什么解开它”chmod 777是在问“谁能读、谁能写、谁能执行”。一旦你理解了命令本身是在向操作系统提问遇到新场景时你就会自然去组合命令而不是每次上网搜答案。Linux 的命令体系有点像你去一个大型机构办事先找咨询台man再找指引牌apropos实在不行还能查历史档案history。真正的高手不是记得所有窗口在哪而是知道怎么问路。1.2 最该记住的不是命令而是“帮助系统”Linux 自带一个被很多人忽略的宝藏man。大部分人只在报错时看一眼其实它是最好的命令字典。比如你想知道tar到底有哪些参数直接man tar不过man对新手不太友好内容又长又密。我平时更喜欢先用tldr这类工具它把常用参数和典型用法浓缩成几行示例tldr tar如果系统里没有tldr可以用apt install tldr或者dnf install tldr装一个装完你就知道查命令的速度能提升多少。还有一个容易被忽略的命令是apropos它按关键词搜索手册页。比如你忘了“修改文件所有者”的命令叫什么直接敲apropos owner它会列出chown、chgrp等相关的命令。这才是“学习 Linux 常用命令”的正确姿势不需要把所有命令都塞进脑子只要知道怎么找到它们就行。1.3 把 history 变成你的“第二大脑”很多人在终端里反复敲同一条长命令敲的时候又怕敲错。其实 Bash 有个非常好用的机制按CtrlR进入反向搜索输入几个字母就能找到历史命令。配合history命令你还能看到自己最近干过什么。history | grep docker这个组合能帮你复盘上一次部署时到底执行了哪些步骤某条命令后面跟了什么参数很多线上事故就是因为“当时随手敲了个命令事后忘了具体参数”造成的。我个人的习惯是每次做完一次比较复杂的操作就把关键命令记录到项目笔记里而不是指望终端历史永远都在。终端历史文件~/.bash_history默认可能只保存 1000 条重要命令真不一定查得到。这里还有个实用技巧用history配合grep比翻聊天记录靠谱得多。有一次我在排查一台测试机上的服务异常怎么都想不起来之前是用哪个端口启动的后来通过history | grep port直接找到了当时的启动命令问题瞬间定位。这就是“问”终端的力量。2. 文件与目录操作不是“会用 ls”这么简单2.1 ls 和 find定位文件的两个层次ls是大家入门的第一个命令但很多人只会用ls或者ls -l。实际排查问题时我更常用ls -lah其中h让文件大小显示成人类易读的格式a显示隐藏文件l显示权限和所有者信息。这三件套组合在一起能让你一眼看出目录里有没有可疑的隐藏文件、哪个日志文件膨胀得异常。但ls只能看某个目录里的东西想全盘找文件就得用find。很多新手觉得find难因为它参数多。其实核心就几个find /var/log -name *.log -mtime 7这条命令的意思是在/var/log下找所有以.log结尾、并且在 7 天前修改过的文件。-mtime是修改时间7表示超过 7 天-7表示 7 天以内。还有一个容易被忽略的-size参数find / -type f -size 500M这条命令能帮你在磁盘告警时迅速找到大文件。我接手过一台磁盘写满的机器当时靠df -h只看到根分区 100% 使用但不知道谁占的。就是靠这条find命令定位到了某个程序生成的超大日志文件。find还可以配合-exec做批量操作比如批量修改权限find /data/app -type f -exec chmod 644 {} \;{}是 find 找到的每个文件的占位符\;表示命令结束。这种写法规避了写脚本循环的麻烦但也意味着每个文件都会启动一次外部命令。如果文件量特别大性能会有点影响。2.2 cp、mv、rm 背后的风险意识看到cp、mv、rm很多人觉得太基础。但真正让我吃过亏的是rm的不可逆性。有一次我在某台机器上想删除/tmp下的临时目录结果手滑多打了一个空格变成了rm -rf /tmp/ old_data系统直接报错“目录不存在”我才意识到自己差点删错地方。从此之后凡是批量删除我必先ls一遍确认再用find的-name参数过滤出来给rm而不是直接裸敲。删除文件有一个更安全的中间态就是先移动到临时目录mv ./bad_dir /tmp/to_delete_dir/这样即使删错了也有机会从/tmp里找回来。等到确认整个目录确实不需要了再真正执行清理。这个习惯救过我一次当时我把一个配置目录移动到/tmp后来发现线上服务还需要其中一个文件赶紧把它复制了回去。cp和mv也要注意符号链接的问题。默认情况下cp复制软链接时会复制链接本身还是链接指向的文件内容不同发行版、不同参数下行为不一样。我的经验是涉及链接文件就用cp -a保留属性避免搞出“复制过去是个断链”的怪事。2.3 硬链接与软链接什么时候用哪个链接是 Linux 文件系统里特别容易混淆的概念。软链接symlink可以跨文件系统指错了就成断链ls -l会显示箭头目标硬链接不能跨文件系统但它指向的是同一个 inode删除一个链接另一个链接依然有效。日常操作中绝大多数场景用的是软链接比如把某个程序的配置路径链接到实际存放目录ln -s /data/real_config /etc/app_config软链接的好处是灵活切环境时直接把链接指向另外的目录就行。但软链接也有坑有些程序解析配置时会用realpath拿到真正的路径导致你改了软链接指向程序却还在读旧目录。遇到这种情况得查启动脚本里是不是用了realpath。硬链接我一般用来做日志归档的快照式保留比如ln /var/log/app.log /var/log/app.log.$(date %F)创建硬链接后再继续写原文件日志内容不会丢失。这比cp更快因为硬链接不复制数据只是新增一个目录条目。不过硬链接不能在目录和跨文件系统上使用这是它最核心的限制。2.4 tar 和 rsync归档与传输的组合威力打包压缩这件事很多人只会一条tar -czvf但不知道解压时用tar -xzvf更不知道查看压缩包内容可以用tar -tzvf。我处理线上故障时经常要确认压缩包里到底有没有某个配置文件所以习惯先用tar -tzvf backup.tar.gz | grep nginx.conf这样不用解压就能确认内容免得解开大一坨文件后又发现不是自己要的。tar的参数顺序也有讲究-c是创建-x是解压-z走 gzip-v显示过程-f指定文件名。f必须是最后一个参数因为它后面跟的是文件名这是个约定俗成的规矩记不住就容易踩坑。跨机器传文件时我很少用scp硬传大目录而是用rsync。它最大的优势是断点续传和增量同步目录里只有一小部分文件变化时rsync只传变化部分rsync -avz --progress /data/app/ userremote:/backup/app/-a是归档模式保留权限、属主和时间戳-v显示详细输出-z开启压缩。要注意的是源路径末尾的斜杠很有讲究/data/app/表示同步目录里的内容/data/app表示连目录本身一起同步。这个区别曾经让我在某次同步时把目录结构搞错后来只要是备份我都会先写rsync -avz --dry-run跑一遍确认参数无误后再正式执行。3. 进程与系统资源真正排障时先看什么3.1 ps 和 top静态快照与实时视图的配合系统卡了进程没响应大多数人的第一反应是打开top。top确实直观但它是实时视图刷新很快你不一定来得及看清状态。我更喜欢先用ps抓静态快照ps aux --sort-%cpu | head -20这条命令按 CPU 占用率从高到低排序只看前 20 条一眼就能找到谁在吃资源。如果想换成内存排序就用ps aux --sort-%mem | head -20ps aux的输出里STAT列非常关键。R表示正在运行D表示不可中断的睡眠通常是等待磁盘 I/OZ表示僵尸进程。我曾经检查一台文件服务器时发现大量D状态进程后来定位到是底层存储设备的 I/O 排队严重而不是应用代码出问题。这个排查思路在线上非常实用。top适合动态观察变化但它默认显示的 CPU 百分比是单核的多核机器上要按1才能展开每个核的使用情况。更现代一点的替代是htop显示更友好还支持鼠标操作和直接树状查看进程父子关系我基本用它替代top。另外查某个进程是否还在运行用pgrep比ps aux | grep更准确pgrep -fa nginx-f匹配完整命令行-a显示进程名和 PID比裸grep更容易避免误匹配。3.2 端口与连接ss 全面替代 netstat以前排查端口问题都用netstat但新的系统上netstat不一定预装而且输出也比较旧。ss是 iproute2 套件里的工具性能更好输出也更清晰。最常用的场景是查某个端口是否被监听ss -lntp | grep :8080-l只显示监听端口-n用数字显示端口和地址-t只看 TCP-p显示进程信息。加上grep :8080就能定位到 PID。如果端口被占接着用ps -p PID查看具体是什么程序。这比lsof -i:8080更轻量而且不需要额外安装。查看当前 TCP 连接状态也常用ssss -s它显示的是整体连接统计包括建立、等待、关闭等不同状态的数量。排查集群中的大量异常连接时ss -s是第一个看的。如果TIME-WAIT数量特别大多半是频繁创建短连接比如某些请求服务没有启用连接复用。理解这个输出比记十条命令都管用。3.3 磁盘与内存free、df、du 的解读磁盘报警时先看整体df -h-h以易读格式显示。这里有个常见误解df显示的使用率并不代表真正的可用空间因为 Linux 会为 root 保留一部分空间默认一般是 5%。所以当你看到/分区使用率 100% 时进程可能还能写一点看到 95% 时系统可能已经警告了。接着用du找大头du -sh /var/log/*-s只汇总每个目录的总大小-h易读格式。du和前面的find -size是两套互补思路du看目录树find按文件元数据过滤。如果日志目录特别大别忘了du还会把已删除但未释放空间的文件算进去其实不会du查看的是当前目录树里的文件大小。真正占用磁盘但找不到大文件的场景通常是有进程持有已删除文件句柄。这时候用lsof L1它会列出被删除但仍被进程占用的文件。内存方面free -h也是必备free -h输出里有个“buff/cache”列很多新人看到缓存占用很多就慌其实这是内核在用内存做文件缓存压力大的时候会被自动回收。真正需要关注的是available这一列它表示在不触发换页的情况下还能分配多少内存。判断内存够不够看available而不是看free这列这是我反复提醒自己的一个要点。3.4 systemctl 与 journalctl从“启动服务”到“看完整状态”现在的发行版基本都是 systemd 管理服务常用命令也变了。启动、停止、重启、查看状态核心就是systemctl status nginx systemctl restart nginx systemctl enable nginx比service命令更强大的是systemctl list-units --typeservice --statefailed它能列出所有失败的服务。排查机器重启后服务没起来的场景这条命令比逐个status高效得多。服务起没起来日志是关键。journalctl是 systemd 统一的日志查询工具我常用这几种journalctl -u nginx -n 100 journalctl -u nginx --since 10 minutes ago journalctl -u nginx -f-u指定服务单元-n看最后多少行--since按时间过滤-f是实时跟踪。有些程序会写自己的日志文件比如/var/log/nginx/error.log但 systemd 的journalctl里也能看到服务进程的标准输出和标准错误。排查启动崩溃时这两个都要看先看journalctl里有没有段错误或加载失败的信息再看业务日志有没有超时或初始化失败的记录。日志量大的机器journald会吃掉不少磁盘空间。默认情况下日志大小是有限制的但如果你发现/var/log/journal目录异常膨胀可以用journalctl --vacuum-size500M清理到指定大小。这是排查磁盘空间问题的隐藏点很多人du -sh /var/log/*看半天却没注意journal目录。4. 权限、用户与安全底线4.1 chmod 和 chown数字权限的真正含义chmod 777大概是互联网上最常见的错误命令之一。数字权限的含义很简单4是读2是写1是执行三位数字分别对应所有者、所属组、其他用户。777就是所有人完全读写执行等于把你的文件放在大街上任人取用。我见过有人为了让某个 Web 目录能写直接chmod -R 777结果网站被人写入木马整台机器被扫得干干净净。正确的思路是按最小权限给。网站目录只需要被运行用户读写入只需要针对上传目录执行权限只给需要执行的程序。比如chown -R www-data:www-data /data/www chmod -R 750 /data/www chmod -R 770 /data/www/upload这样站点主体是所有者读写执行、组内读取上传目录才允许组写。chown修改所有者和组-R递归。改错了所有者也是常见事故来源所以我每次执行chown -R之前都会先看一眼当前目录的属主防止连系统目录一起改掉。4.2 umask 和默认权限为什么新建文件总是 644很多人疑惑为什么新建的文件是 644新建的目录是 755这不是系统随便定的而是umask决定的。umask是权限掩码默认通常是022。它的计算方式是文件默认最大权限666减去掩码022得到644目录默认最大权限777减去掩码022得到755。为什么文件不是666因为内核默认不给新文件执行权限这是防止你无意中创建一个可执行脚本的安全设计。可以用umask命令查看也可以临时改umask 077改成077后新建的文件是600只有自己能读适合存放密钥或敏感脚本。我一般会在需要处理密钥的项目目录里设置umask 077避免同组用户能读私钥。4.3 sudo 的正确姿势与 sudoers 最小授权sudo不是“万能钥匙”它是受权限策略控制的。它的配置文件/etc/sudoers必须用visudo命令编辑因为visudo会检查语法避免搞坏配置后连sudo都无法使用。这个坑我踩过一次直接改/etc/sudoers改漏了格式导致该机器所有用户都没法执行sudo最后只能通过另一个管理员账号接管修复。日常授权时不要直接给用户ALL(ALL) ALL那是把整个机器的 root 权限交出去。最小授权应该是这样deploy ALL(ALL) /usr/bin/systemctl restart nginx表示deploy用户只能以 root 身份执行systemctl restart nginx。这样的好处是某用户只能重启 Nginx却不能改系统配置。对需要执行多个命令的场景可以建一个组把命令列表写进sudoers%ops ALL(ALL) /usr/bin/systemctl restart *, /usr/bin/journalctl但这也有个隐患*通配符有可能被用户注入额外参数比如/usr/bin/systemctl restart nginx; /bin/bash。所以更严格的策略是把命令路径写死或者用包装脚本。关于安全策略不要过度信任 sudoers 的花哨写法简单明确最稳。4.4 登录安全基础passwd、last、whoLinux 日常命令里用户和登录相关的几个命令也值得补充。last可以查看最近的登录记录last -20它能显示登录时间、来源 IP 和持续时长。排查服务器是否被人暴力尝试登录我一般配合/var/log/auth.log或/var/log/securegrep Failed password /var/log/auth.log | tail -20如果发现有大量来自不同 IP 的失败尝试就需要考虑禁用密码登录、改用密钥认证或者安装防暴力破解工具。改用户密码用passwd 用户名锁定账号用usermod -L 用户名解锁用usermod -U 用户名。还有一个小命令是who查看当前谁在线w可以显示在线用户正在执行什么命令。排查“谁在乱动系统”的时候w的输出非常有价值。5. 文本处理三剑客grep、awk、sed 的配合5.1 grep从暴力搜索到精准过滤grep是日志分析的基础。简单搜索grep ERROR /var/log/app.log但真正用好的关键是参数。-E支持扩展正则更有人性化的体验-i忽略大小写-v反向匹配排除你不想看的内容-l显示包含匹配内容的文件名-c计数。我处理日志时最喜欢的是这套组合grep -E ERROR|WARN /var/log/app.log | grep -v healthcheck先过滤出错误和警告再排除健康检查的无聊日志。还能用-A 3 -B 2打印匹配行的上下文能帮你搞清楚错误发生前后的状态grep -B 3 -A 5 OutOfMemoryError /var/log/app.log-B 3是匹配行前 3 行-A 5是后 5 行。排查崩溃原因时上下文比单行信息重要得多。5.2 sed流编辑器的典型应用sed最常被用来替换文本sed -i s/old/new/g config.conf但-i会直接改原文件这是很多人害怕的地方。我建议先在无-i的情况下跑一遍确认输出正确sed s/old/new/g config.conf | head -20确认无误后再加-i。sed还有一个删除行的场景比如去掉配置文件里的空行和注释sed -i /^$/d; /^#/d config.confd表示删除匹配行。不过这种操作要非常小心如果配置文件里包含了以#开头的密码占位符删除后配置直接废了。所以我的习惯是先用grep -n查看要删的匹配内容再执行sed -i。sed的另一种常见用法是取某一段文本。比如只想看日志文件的 100 到 200 行sed -n 100,200p app.log-n关闭默认输出p打印指定范围。这在日志文件特别大无法用文本文档打开时非常有用。5.3 awk列处理用它别再用循环如果说grep是行过滤器sed是文本编辑器awk就是列处理器。它默认以空白字符分割字段$1是第一列$2是第二列$NF是最后一列。最简单的用法是提取某个字段awk {print $1} app.log它的真正威力在于按条件处理。比如从访问日志里提取状态码为 500 的请求 IPawk $9 500 {print $1} access.log | sort | uniq -c | sort -rn | head -20这条命令一口气完成了匹配状态码 500、提取 IP、统计次数、按次数排序、取前 20。sort和uniq也是文本处理里的黄金搭档。uniq -c会统计连续重复的行次数注意是“连续”所以必须先sort再uniq不然相同内容分散在不同位置会统计不出来。awk里还可以做简单计算。比如统计平均响应时间awk {sum $NF; count} END {print sum/count} access.log假设最后一列是响应时间。这个技巧在分析接口耗时的时候特别有用不用写一个完整的脚本一行命令就能得到结果。5.4 组合实例从日志里找出最慢的请求这里的例子可以把三个工具串起来。假设访问日志格式是192.168.1.10 - - [12/Oct/2025:10:15:30 0800] GET /api/order HTTP/1.1 200 532 1.253最后一列是处理耗时。我想找出最慢的 10 个请求及其对应接口awk {print $NF, $7} access.log | sort -rn | head -10awk提取耗时和请求路径输出成“耗时 路径”两列sort -rn按数字降序排列head -10取前 10 条。但这里有个细节如果日志里某些字段不是固定位置比如 IP 是-或缺字段awk的列号就会错位必须先用真实日志样本验证字段位置。我处理过不同格式的日志有的用$7是请求路径有的是$6稍微差一个字段结果就完全没意义。所以每回处理前都先head -5看日志结构再决定列号。要想看某段时间窗口内的慢请求可以配合sedsed -n /12\/Oct\/2025:10:15/,/12\/Oct\/2025:10:30/p access.log | awk {print $NF, $7} | sort -rn | head -10这里用sed先圈出时间范围再交给awk处理。三个命令各有分工各自只做一件事组合起来就成了一条小型流水线。Linux 的设计哲学在命令行里体现得淋漓尽致小工具协作而不是用一个巨型工具包打天下。6. 网络诊断链路从 ping 到 curl6.1 ping 和 traceroute先确认通不通网络排查的第一步永远是确认连通性。ping是最直接的ping -c 4 192.168.1.100-c 4指定发 4 个包。看结果时重点不是“丢包”那行而是延迟有没有波动以及是否出现Destination Host Unreachable。如果跨机房访问很慢用traceroute看每一跳的延迟traceroute -n 8.8.8.8-n不做域名反解速度更快也避免 DNS 拖慢输出。不过traceroute用的是 UDP 或 ICMP有些网络设备会限制这类探测包导致结果看起来像丢包但实际业务是通的。所以它的输出只能作为参考不能单独下结论。这时候换个思路用tcping或连接真实端口来测更贴近业务路径。6.2 ss 和 lsof谁占用了端口端口被占是后端开发最常遇到的报错。ss -lntp应该成为你的肌肉记忆ss -lntp | grep :8080如果输出显示某个 PID 占用了端口再查进程详情ps -p 1234 -f如果进程不存在但端口还占着变成“孤儿连接”通常需要确认是不是还有其他进程在监听或者该端口处于TIME-WAIT状态。lsof -i:8080也能查但lsof不一定预装ss是更通用的方案。还有一种情况是端口没被监听但客户端连接被拒绝这时要确认防火墙规则iptables -L -n | grep 8080云服务器上的安全组和本机防火墙是两层都要检查。很多新手只盯着本机防火墙忘了云控制台里还有一层规则结果防火墙明明放行了公网还是连不上。6.3 dig 与 curl解析和请求层的验证排查域名问题dig比nslookup更清晰dig example.com short它会返回解析后的 IP。想指定 DNS 服务器测解析直接后面跟上服务器地址dig 8.8.8.8 example.com short而curl是请求层最常用的诊断工具。我几乎每天都用curl -v看完整链路curl -v https://example.com/api/health-v会输出 DNS 解析、TCP 连接、TLS 握手、HTTP 请求响应头。如果连接失败它能告诉你卡在哪个环节是 DNS 解析不出是 TCP 连接被拒还是证书验证失败。curl -I只拿响应头适合快速确认服务是否存活curl -I http://127.0.0.1:8080/health如果本机curl正常但外部访问失败问题就在网络链路、防火墙或反向代理上如果本机也失败问题在服务本身。6.4 一条完整的排查思路实战中我通常按这四层走。第一层是本机进程ss -lntp看服务有没有监听端口第二层是本机请求curl -v http://127.0.0.1:端口/health看服务是否正常响应第三层是网络链路跨机器ping和traceroute看路由和延迟第四层是外部访问确认防火墙规则与域名解析是否正确。有一次排查一个“外部无法访问”的问题我按这个顺序走下去发现本机curl正常、同机房另一台机器也正常但公网 IP 访问不通。最后定位到是云控制台的安全组没有放行新端口而本机防火墙是放开的。这个经验告诉我越接近用户侧的排查越要先考虑平台层和安全策略不要总盯着应用代码。网络诊断里还有一个容易被忽略的命令mtr。它结合了ping和traceroute的能力持续显示每一跳的丢包率和延迟比单独跑traceroute更直观。遇到网络质量问题我的首选就是mtr -n 目标IP持续观察几十秒再结合出口流量和带宽占用情况判断是不是链路拥塞。写完这些我发现真正拉开运维效率差距的往往不是多冷门的命令而是面对问题时的排查顺序。常用命令就那么几十条难的是把它们组合成一条顺畅的思路先问进程再问端口然后看日志最后用文本工具从日志里提取规律。我也不建议一口气学完所有东西先把手头的场景用熟比如这周只练文件操作和find下周只练进程和端口等这些组合变成肌肉记忆再往上叠加网络和文本处理工具。那时候你再回头翻“Linux 常用命令”清单会发现绝大多数命令本来就认识只是以前没想过它们可以这样配合。