ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux命令实战指南:从文件查找到网络排查的高效工作流

Linux命令实战指南:从文件查找到网络排查的高效工作流

很多接触Linux的朋友,最初都是靠死记硬背命令入门的。ls、cd、cat、grep……背了一堆,可真到了服务器上处理问题,或者需要写个脚本完成自动化任务时,脑子里的命令就开始打架:这个参数是干嘛的?那个选项加了会不会有风险?输出结果怎么跟我想的不一样?

这篇博文我不打算给你罗列一份“命令大全”——那种东西网上到处都是,查起来比字典还枯燥。我想换个角度,从实际做事的逻辑出发,把Linux命令拆解成几类核心场景。比如怎么高效地找文件、怎么处理文本、怎么排查网络和进程问题、怎么安全地给用户授权、怎么做备份压缩。每讲一个场景,我会把其中最常用的命令、最容易踩的坑、以及我实际工作中验证过的用法一起说清楚。你把这些内容串起来用,比单独记几十条命令要实用得多。

不管你是在用Ubuntu做开发,还是用CentOS跑生产服务,亦或是管理一堆云主机,这套思路都是通用的。命令有差异,但解决问题的框架不变。

1. 命令的底层逻辑与高效工作流

刚开始学Linux,很多人都会问一个问题:命令这么多,怎么记?

我的看法是,你先别急着记,先理解Linux的设计哲学。它的核心思想是“一个命令只做好一件事,然后把它们组合起来”。这也是为什么你经常能看到一长串用管道符|连接的命令,比如ps aux | grep java | grep -v grep。这种体操般的操作,本质上是在用系统提供的“积木块”搭建一个临时的、契合当前需求的工具。

理解了这一点,你的学习路径就会清晰很多:

  • 先掌握每个命令的“基本功能”,也就是它是干什么的。
  • 再掌握几个高频参数,不需要背全。
  • 最后学会用管道、重定向、通配符把这些命令串起来,解决复杂问题。

我个人非常推荐一个习惯:先看帮助,再动手。不需要一上来就翻几百页的文档,直接在你当前用的机器上跑man 命令名或者命令名 --help,快速扫一眼options列表,找到你需要的那个参数。用多了自然就熟了。

还有一个能明显提升效率的小技巧:熟悉Tab键补全。不管是命令、文件名还是路径,打几个字母按一下Tab,系统能自动帮你补全,还能避免因为拼写错误导致的莫名报错。如果你发现Tab没反应,多半是当前目录下有多个相同前缀的文件,再按一次Tab它会把候选列表列出来。

1.1 Shell到底是什么,为什么它如此重要

你输入命令的界面,叫Shell。它本质上是一个翻译官,负责把你输入的指令翻译给系统内核去执行。常见的Shell有bash、zsh、sh。绝大多数Linux发行版默认都是bash。

你在网上看到的大部分教程、脚本,默认也都是在bash环境下运行的。所以刚开始学,老老实实用好系统默认的bash就够了。没必要一开始就折腾zsh、配置oh-my-zsh什么的,那是后面提升体验的事,跟“会用Linux”没有直接关系。

Shell的另一个重要作用,是它自带一套简单的编程语言。你可以把多条命令写进一个文本文件,起个名字叫xxx.sh,然后执行它。这就是脚本编程的开端。我在后面讲到的很多操作,其实都是手工执行命令,但你可以发现,它们稍加改动就能变成一段自动化的脚本。

1.2 管道、重定向与通配符:组合命令的三种武器

单打独斗的命令作用有限,真正厉害的是组合。

**管道(|)**的作用是把前一个命令的输出,作为后一个命令的输入。比如ls -l | grep "txt",意思就是先列出当前目录所有文件的详细信息,然后从这些信息里筛出包含“txt”的行。

**重定向(>、>>)**的作用是把命令的输出写到文件里。>会覆盖文件原有内容,>>则在文件末尾追加。比如echo "hello" > test.txt,就把hello写进了test.txt。注意,>这个符号很危险,如果文件本来有内容,它会直接清空再写入。我见过不止一次有人想写日志,结果>用错了地方把重要配置内容覆盖了。建议养成习惯:除非你确定要清空覆盖,否则追加用>>。

**通配符(*、?、[])**则用来模糊匹配文件名。*.log匹配所有以.log结尾的文件,file?.txt匹配file1.txt、file2.txt这种单字符变化的文件。这几个符号看着简单,但用好了能省不少事。比如你要删除一堆临时文件,rm -rf /tmp/*.tmp,这就是通配符的威力。

这三个工具加上命令本身,就构成了你在Linux世界的基本工作方式。别小看这些基础概念,很多程序员写了几年代码,这些技能依然能派上大用场。我自己处理服务器问题时,大量时间都在用这些最基本的组合技定位问题。

2. 文件与目录操作:在服务器上找东西的本事

文件系统是Linux一切的基础。你写的代码、配置的服务、产生的日志,全部以文件形式存在。所以文件操作命令熟练度,直接决定了你在服务器上干活的速度。

2.1 ls、cd、pwd:确认你身处何方

这三个命令属于“肌肉记忆”级别的。

pwd显示当前所在目录,全称是Print Working Directory。当你迷失在多层目录中,或者脚本需要知道当前路径时,它就是救命的。cd切换目录,cd ..返回上级,cd ~回到用户主目录,cd -返回上次所在目录,这个很有用,在两个相隔很远的目录间反复横跳时能省不少事。

ls则是查看目录内容的命令。但很多人只用ls,不知道ll和ls -lah的价值。ll在部分系统上是ls -l的别名,能显示权限、属主、大小、修改时间。ls -lah则能以人类可读的方式显示文件大小(比如K、M、G),还能显示隐藏文件(以 . 开头的文件很多是配置文件)。我看到不少同事排查问题的时候,上来就cat一个文件,结果找不到,就是因为被隐藏目录挡住了视线。

这里有个小经验:养成用ls -lah代替ls的习惯。看清权限、看清大小、看清隐藏文件,这些信息无论在日常开发还是问题排查中,都能给你提供线索。比如你发现某个日志文件异常大,可能就是程序有bug在疯狂打印,这就能顺藤摸瓜找到问题。

2.2 cp、mv、rm:增删改查要谨慎

文件操作里,最容易出事的是rm,其次是mv。

cp -r递归复制目录,mv移动或重命名,rm -rf强制删除目录。这些命令本身不复杂,复杂的是你要有敬畏心。我常用的安全策略是:

  • 删除文件之前,先明确列出当前目录内容,确认自己要删的东西在不在。执行rm时,尤其是rm -rf,先想三秒钟。
  • 尽量少用rm -rf这种组合。如果非用不可,路径一定要写全。曾经有人想删某个目录下的临时文件,结果因为cd跑到了根目录又执行了带空格的错误路径,差点酿成事故。
  • mv命令在跨文件系统移动时,实际上是复制+删除,如果中途断电或者空间不足,可能会产生不完整文件。需要移动大文件(比如好几个G的数据库备份)时,我一般用cp先复制到目标位置,确认完整后再删原文件。

2.3 find:解决“我知道有个文件,但不知道在哪”

find是Linux里最强大的文件搜索工具,没有之一。它的效率比locate低,但胜在实时和精准。

最基本的用法是find /path -name "文件名"。比如find /var/log -name "*.log",就能列出日志目录下所有.log文件。还可以按大小、时间、类型查找。比如:

# 找大于100M的文件 find / -type f -size +100M # 找最近7天内修改过的配置文件 find /etc -type f -mtime -7 # 找某个用户所有的文件 find /home -user zhangsan

另一种常被忽略但实际很有用的查找文件方式,是用which。which和find不同,它专门用来查找命令所在的路径。比如which java,能告诉你当前环境中Java可执行文件的路径。这在排查环境变量问题时特别管用。如果你which不到一个命令,大概率是没安装,或者安装位置不在PATH路径里。

2.4 du与df:一眼看出磁盘空间去向

服务器磁盘爆掉是运维里最常见的故障之一。处理这种问题,你需要的不是ls,而是du和df。

df -h查看磁盘分区的使用情况,一目了然,哪个分区满了,还剩多少空间。du -sh查看当前目录总占用大小,du -h --max-depth=1查看一级子目录的占用。当你发现根目录满了,一步步du -h --max-depth=1往深层走,很快就能定位到到底是哪个目录在疯狂吞噬空间。找到后,再去那个目录里ls -lahS,按大小降序排列,立刻能看到最大的文件是哪个。

这招在排查服务器空间告警时非常实用。有一次我接手一台机器,也是根分区满了。我按这个思路,最后发现是某应用的日志文件在几天内涨到了几十GB,把整个磁盘挤爆了。定位到问题后,处理方案就清晰了:清理旧日志,然后去应用配置里把日志级别调低、切割策略改合理。

3. 文本处理三剑客:grep、awk、sed

搞Linux的人常说文本处理三剑客:grep、awk、sed。这三个命令,可以说是服务端开发与运维的“内功心法”。它们也许不如一些编程语言功能全面,但在处理结构化的文本数据(日志、配置文件、系统输出)时,效率是惊人的。

3.1 grep:在海量日志里捞针

grep按行处理,搜索包含指定关键词的行。它是我日常用得最多的命令,没有之一。一个典型的排查场景:服务报错了,你去日志里找错误信息。

# 在app.log里找ERROR,并显示行号 grep -n "ERROR" /var/log/app.log # 忽略大小写搜索error grep -i "error" /var/log/app.log # 找到ERROR之后,顺便看上下文各5行 grep -n -C 5 "ERROR" /var/log/app.log

-C 5这个参数(context的缩写)非常实用。单看一行错误日志往往看不出原因,需要结合前后几行的堆栈信息、调用参数才能定位问题。很多时候,真正的问题日志是静默的,错误只是结果。这就需要你看上下文,把前戏和后遗症一起读完。

还有两个常用变体:grep -v表示反向匹配,排除包含指定关键词的行;grep -E表示使用扩展正则表达式,比如grep -E "ERROR|WARN"同时匹配多个关键词。这些组合加上管道,就能做很多精细的过滤。

3.2 awk:不只是按列取数据

如果说grep是按行过滤,那awk就更适合按列处理。它的经典用法是:awk '{print $1}',把每一行按空格(或指定分隔符)切开,然后打印第几列。比如ls -l的输出,第3列是属主,第4列是属组,第5列是文件大小。想列出所有文件的大小和文件名,就可以ls -l | awk '{print $5, $9}'。

awk真正强大之处在于它是一门小的编程语言,支持变量、循环、条件判断、内置函数。比如你想求一个文件里所有数字的和:

awk '{sum += $1} END {print sum}' numbers.txt

这个能力在处理统计数据时非常实用。比如从一份访问日志里统计每个接口的访问量,awk配合sort和uniq能做到。我平时查看日志时,常这样统计“某个时间段内错误出现了多少次”,几秒钟就能出结果,而类似的需求如果用程序实现,可能要写几十行代码。

3.3 sed:流式编辑,批量替换的利器

sed的名字来自Stream Editor,流编辑器。它的核心能力是按行读取文件,修改后输出。最常见的需求是批量替换。比如:

# 把文件里的hello都替换成world,并直接修改原文件 sed -i 's/hello/world/g' test.txt # 删除第10行到第20行 sed -i '10,20d' test.txt # 只打印包含ERROR的行(类似grep) sed -n '/ERROR/p' app.log

-i参数表示in-place,也就是直接改文件。这个参数是好东西,但也很危险。我在刚接触时,有一次想批量替换配置文件里的IP地址,结果-i用下去,正则写错了,把不该替换的内容也改了。幸好那天有备份,否则就麻烦了。后来我养成了一个习惯:使用sed -i之前,先不带-i跑一遍看输出结果,确认无误后再执行真正的修改。或者,干脆先把原文件复制一份,再做修改。

4. 用户管理与权限控制:安全底线,不可马虎

Linux是一个多用户操作系统。权限控制是它的核心安全机制。做开发或者运维,你需要经常跟用户、组、文件权限打交道。这部分的命令不多,但非常重要。权限弄错了,轻则服务跑不起来,重则安全隐患。

4.1 chmod与chown:读、写、执行的哲学

Linux里每个文件都有三种权限:读(r)、写(w)、执行(x),分别对应数字4、2、1。这三个数字相加,就得到了一个权限总和。比如7=4+2+1,表示可读可写可执行;6=4+2,表示可读可写;5=4+1,表示可读可执行。

chmod修改权限。常用方式有两种:符号方式(u+x,给用户加执行权限),数字方式(chmod 755 file,即属主7、属组5、其他人5)。我强烈建议你用数字方式,因为它更精确、可预测。

$ chmod 755 deploy.sh # 属主完全控制,其他用户可读可执行 $ chmod 600 config.yml # 只有属主可读写,配置文件常见设置

chown修改文件属主和属组。比如chown -R www:www /data/www,将整个网站目录的属主和属组都改成www用户。这个操作在部署Web服务时几乎是必须的。如果你发现Web服务器没有权限读取文件,先别急着chmod 777,先看看属主对不对。chmod 777是大忌,它意味着任何用户都能读写执行该文件,对生产环境是灾难。

4.2 用户与组:如何优雅地授权

创建用户、加入组、设置密码,这些操作在初期不多,但用到时很关键。

  • useradd创建用户,比如useradd -m -s /bin/bash dev01,-m自动创建home目录,-s指定shell。
  • passwd设置或修改密码。
  • usermod -aG sudo dev01把用户加入sudo组,赋予管理员权限。
  • groupadd创建用户组,方便批量管理权限。

有个经验是:尽量不要让应用直接跑在root用户下。很多安全工具、巡检脚本,都会把这个标记为高风险项。正确做法是创建一个独立用户,只给该给它权限的目录授权。比如跑Java应用,就建一个叫app的普通用户,把应用目录和数据目录的属主交给它,这样即使应用被攻破,攻击者也只能在这些目录里折腾,不能把整台机器玩弄于股掌之间。

4.3 sudo:临时管理员身份的正确姿势

sudo允许普通用户以root身份执行特定命令。它的配置文件是/etc/sudoers,修改它必须使用visudo命令(这个命令会做语法检查,防止你写错导致sudo完全用不了)。

我常听到有人问:为什么我执行yum install xxx提示无权限?答案是,你的账户不在sudo组里。解决方案很简单:usermod -aG sudo yourname,然后重新登录一次。

使用sudo时,有一个小细节:sudo默认会记录所有输入的命令(审计日志)。这是个很好的安全特性。如果一台服务器出问题了,你可以查看/var/log/auth.log,追踪谁在什么时候执行了什么管理命令。这能帮你回溯操作,定位是否有人误操作。

5. 进程管理与系统监控:洞察机器内部的运行状态

你部署的服务,本质上都是一个进程。想让服务稳定高效地跑,就得学会查看进程状态、管理进程生命周期、监控系统资源。这部分命令是解决“机器卡了、应用挂了、CPU飙了”这类问题的核心工具。

5.1 ps、top、htop:一眼看穿进程真相

ps -aux能列出当前系统所有进程。输出里,PID是进程号,%CPU是CPU占用百分比,%MEM是内存占用,COMMAND是启动命令。这个命令是我排查“哪个进程在消耗资源”的第一选择。配合管道,ps aux --sort=-%cpu | head -10可以直接列出CPU占用最高的前10个进程。

top是动态的,相当于任务管理器,实时刷新系统资源占用。输入top后,按大写的P按CPU排序,按大写的M按内存排序,按q退出。这些都是实用操作。htop是增强版,界面更友好,支持鼠标操作,但需要额外安装。如果你的系统里已经装了,不妨直接用htop;没装的话,先掌握top也足够应付大多数情况。

看进程信息时,我建议你特别关注一个字段,叫STAT(状态)。比如S表示睡眠,R表示正在运行,Z表示僵尸进程。如果出现一堆Z进程,说明父进程没有正确处理子进程退出信号,程序有bug,需要重视。

5.2 kill与进程生命周期管理

进程管理里,终止进程是个高频操作。kill命令通过信号来终止或影响进程。

# 正常终止进程,请求进程自行清理后退出 kill PID # 强制终止进程,直接杀死 kill -9 PID # 挂起/暂停进程 kill -STOP PID

kill默认发送的是SIGTERM(信号15),它比较“礼貌”,给了进程处理善后(比如保存文件、释放资源)的机会。kill -9发送的是SIGKILL,操作系统直接强制回收,不给任何机会。很多对稳定性要求高的服务(比如数据库),如果直接kill -9,可能会导致数据未落盘、文件损坏。

所以我的习惯是:先kill,等待几秒,不行再kill -9。这就像给人发“裁员通知”:先给个协商机会,谈不拢再直接强制执行。不过有些场景,比如进程已经死锁、卡住不动了,就没必要等,直接kill -9快速恢复服务更重要。这个度,要根据服务的类型和当前的状态来判断。

5.3 后台运行与日志追踪:搞定部署任务

部署一个服务后,怎么让它持续在后台运行,而不是关掉终端就断?这是初学者最常见的困惑之一。我见过不少新手用nohup挂后台,但不知道日志怎么看。

nohup的意思是“忽略挂断信号”,配合&符号,可以让命令在后台持续运行,即使你退出了终端,进程也不会被终止。

# 后台运行Java应用,日志输出到app.log nohup java -jar myapp.jar > app.log 2>&1 &

这里的> app.log把标准输出重定向到日志文件,2>&1把错误输出也指向同一个地方(这步很关键,否则你看不到报错),最后的&表示放入后台执行。

跑起来之后,怎么看日志?最常用的是tail -f app.log,它会持续追踪文件新增内容,实时打印出来。排查问题时,先tail -n 100 app.log看最近100行,再结合tail -f看实时输出,效率很高。如果日志文件太多,可以先grep过滤关键词再tail。

6. 网络排查三板斧:ping、telnet、curl

服务器跑着跑着,突然连不上了,或者接口超时了,这种问题几乎每个人都遇到过。排查网络问题,有一整套从底向上的基本流程。核心命令就几个:ping、telnet、curl、ss。

6.1 网络通路诊断:先分清楚是不是网的问题

ping用来测试网络连通性,比如ping baidu.com,能确认当前机器是否能访问外网、DNS解析正不正常。但它只能证明“网络通”或者“网络不通”,不能深入检测端口、协议这些细节。

网络不通时,先ping一下网关,再ping一下外部IP,就能大致分段定位:是本机网卡问题、交换机问题,还是路由不通。这个排查思路就像水管堵了,先看入户总阀,再看楼层阀门,最后查自己家水管。

telnet测试一个IP的某个端口是否开放、是否可达。比如想确认某台服务器的3306端口(MySQL)能不能连,执行telnet 192.168.1.10 3306。如果显示Connected to ...,说明端口可达;如果卡住不动或提示Connection refused,说明目标主机端口没开,或者有防火墙拦截。这个命令是排查“服务没起来”和“端口被防火墙挡了”的利器。

不过有些新装的系统没有telnet客户端,这时可以用ncat或者nc(netcat的简称)来做类似的测试:

nc -zv 192.168.1.10 3306

-z表示扫描模式不发送数据,-v显示详细信息。效果和telnet类似。

6.2 HTTP接口调试全靠curl

curl是命令行下的HTTP请求工具,功能极强,几乎可以模拟任何HTTP请求。排接口问题、测试Web服务、调用第三方API,全靠它。

# 简单GET请求,看响应头 curl -I https://example.com # 带请求头、POST数据 curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' http://localhost:8080/api # 下载文件并保存为指定名字 curl -o newname.tar.gz http://example.com/file.tar.gz # 查看详细的通信全过程(调试利器) curl -v http://localhost:8080/health

-v参数是我最常用的调试利器,它会显示整个HTTP通信的细节,包括DNS解析、TCP连接、发送的请求头、收到的响应头。当接口返回错误时,先用curl -v看一遍全过程,大多数问题(域名解析失败、连接被拒、重定向跳转、返回状态码)都能直接看出来。

6.3 ss:更现代的端口查看工具

曾经的主流工具叫netstat,现在很多新系统已经用ss替代了它。ss(Socket Statistics)命令更快、显示的信息更全。常用用法:

# 查看所有监听中的端口 ss -tlnp # 查看所有TCP连接 ss -tnp

其中-t指TCP,-l指监听中的,-n显示数字形式的IP和端口,-p显示对应的进程信息(需要root权限)。当你需要知道“这个端口是被哪个进程占用的”时,ss -tlnp一次全看清楚。这个信息在服务启动失败、端口冲突、需要kill掉占用进程时,是必需的第一手资料。

7. 实用小贴士与故障排查速查表

讲到这里,Linux常用命令的骨架算是立起来了。最后分享几个我个人的习惯和心得,再整理一张排查手册,方便你在遇到具体问题时快速查阅。

7.1 历史、别名与补全:提升效率的“三件套”

在Linux下,效率往往不是敲命令快,而是“复用”快。

  • 用history查看历史命令,Ctrl + R反向搜索历史。比如你几天前跑过一个很长的命令,忘记了具体参数,Ctrl + R输入几个关键词,就能把它捞回来。
  • 用alias给常用命令起别名。比如我习惯把alias ll='ls -lahF'写进~/.bashrc,每次shell启动自动加载。你还可以把一些固定组合,比如alias grepv='grep -v grep',设置为快捷命令,减少重复劳动。
  • 别忽略bash的自动补全。除了文件名补全,很多命令还支持参数补全(比如systemctl服务名补全)。按一下Tab不响应时,按两下看列表,熟能生巧。

7.2 遇到“Connection refused”的几个排查思路

这是每个人都会遇到的报错。看到它,先别慌,按顺序查:

  1. 进程还在吗:ps aux | grep 应用名,确认服务是否真的活着。很多服务会崩在内网环境里,但因为没有外部探测,一直没人发现。
  2. 端口监听了吗:ss -tlnp | grep 端口号,看服务有没有监听在那个端口上。如果进程活着但没监听,大概率是启动参数、配置文件有问题,服务绑定到了别的地址(比如127.0.0.1而不是0.0.0.0)。
  3. 防火墙拦截了吗:这个在云服务器上特别常见。curl -v如果能通,但外部访问不通,那基本就是安全组或iptables的问题。本地排查可以先systemctl status firewalld看看防火墙状态。

7.3 磁盘空间与性能告警的应急处理顺序

当收到磁盘告警、系统卡顿告警时,我惯用的处理顺序是:

  1. df -h看哪个分区满。
  2. du -h --max-depth=1逐层定位大目录。
  3. ls -lahS找到目录里最大的文件,判断是不是日志。
  4. 如果是日志,先清理(cat /dev/null > 文件名.log,这个操作比rm好,文件句柄还在,服务不用重启,而且能立刻释放空间)。然后回到应用配置里,把logrotate日志轮转和级别调优打开,避免下次再因为日志膨胀把磁盘写满。
  5. 如果是数据库文件,那就得检查数据库自身的清理策略、数据归档方案,这些就不是简单的删文件能解决的了。

如果机器CPU跑满、负载飙升,我会先top看哪些进程在吃CPU,按P排序。如果是正常业务进程,比如数据库做全表扫描,那就得优化SQL或者扩容;如果是异常的进程(比如挖矿程序),那就要立刻断开外网,分析进程的路径、启动方式,修复安全漏洞。

7.4 关于查找人与查错文档的一些心得

很多人习惯遇到问题就去群里问“xxx怎么办”,或直接搜索“Linux xxx命令”。但我的经验是:很多问题,在man手册和系统自带日志里,就有准确答案。

比如man grep能给到所有参数的说明,info命令能提供更详细的手册。把这些“报纸”读好,你自己的排错能力会逐日提升。更重要的是,每个命令的帮助里还有“EXAMPLES”段,很多写得很干货,是官方给的示例,直接参考、修改就能用。

最后再补充一个小技巧:当你修改了某个配置文件、不确定语法对不对时,很多服务提供了验证命令。比如nginx -t、systemctl status、sshd -t。这些命令相当于服务的“体检卡”,配置改错了它能第一时间指出来,避免你把服务重启后才发现起不来、整站宕机。

Linux的学习曲线确实陡峭,但一旦建立起“理解逻辑、善用组合、勤查帮助”的思维方式,很多问题就会变得水到渠成。希望这篇内容能帮你少走一些弯路,在实际操作里少踩一些我已经替你踩过的坑。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进