Linux常用操作命令深度梳理:从命令行为逻辑到高效问题排查
Linux常用操作命令完全梳理从敲不出命令到流畅排查问题我做Linux运维这些年最深的感受是网上随便一搜就是各种Linux常用操作命令大全但大部分只是把man手册翻译了一遍看的时候觉得都会真到线上出问题时还是不知道用哪条命令、输出该怎么解读。所以我一直觉得命令本身不是重点重点是理解每条命令的行为逻辑——它默认做了什么、输出里的每一列代表什么、在什么场景下会坑你。这篇文章我不会给你堆砌几百条冷门参数而是按真实工作场景重新梳理Linux最常用、最高频的操作命令每条都附上我实际使用时的习惯和踩过的坑。适合刚接触Linux的初学者也适合用了两三年还依赖图形界面的开发者跟着过一遍能少走很多弯路。1. 文件与目录操作高频命令背后的行为逻辑1.1 ls、cd、pwd基础到容易被忽略的细节Linux里打交道最多的对象就是文件ls很可能是你敲出的第一个命令。但说实话大多数人只会用ls看个文件名顶多加个-l看权限再往深了问就答不上来了。先说ls -l的输出第一列是权限位总共10个字符第一个字符表示文件类型-是普通文件d是目录l是软链接c是字符设备b是块设备。后面9个字符分成三组分别对应属主owner、属组group、其他人others的r读、w写、x执行权限。这个权限位经常坑人。我遇到过不止一次业务方说文件就在服务器上程序却报Permission denied登上去一看文件权限是600只有属主能读写而程序是用另一个用户启动的。所以看到权限报错第一反应不是怀疑防火墙而是先看权限位这个顺序很重要。ls还有几个参数值得形成肌肉记忆。ls -lh里的-h会把文件大小显示成人类易读的K、M、G而不是一堆字节数ls -lt按修改时间倒序排列排查今天改了哪个配置文件时特别好用ls -la会显示包括以点开头的隐藏文件在内的所有文件。家目录下的.bashrc、.ssh这类隐藏配置不加-a是看不见的。cd命令这里补一个小技巧cd -可以在最近两次所在目录之间来回切换这在两个项目目录之间反复横跳时非常顺手比重新输入一长串路径高效得多。另外注意pwd有两个版本默认的pwd显示的是逻辑路径也就是你cd进去时用的路径pwd -P显示的是物理路径会把软链接解析到底。我在排查那种明明文件在A处程序却说找不到的问题时pwd -P帮过大忙——当时项目里有一个软链接指向了旧版本的目录服务启动脚本还在用旧路径拼接配置pwd -P一执行真实路径立刻现形。1.2 cp、mv、rm每个操作都要有安全意识cp、mv、rm这三兄弟是日常最频繁的操作同时也是事故高发区。cp复制时一定要留意参数。复制目录必须加-r递归否则会报omitting directory。覆盖文件时默认不会提示如果不想让同名旧文件被悄悄覆盖加-i参数每次覆盖前都会让你确认。批量复制时加-i尤其重要我见过有人写脚本循环复制配置结果旧配置被新配置覆盖得干干净净回滚都没法回滚。mv用来移动或重命名文件。这里有个反直觉的点mv和cp不同移动文件到另一个目录时如果目标目录跨文件系统底层其实是先复制再删除耗时和cp差不多如果是在同一文件系统内只是修改目录项指针瞬间完成。所以看到mv大目录很慢时别惊讶先确认是不是跨分区了。rm是真正的重灾区。rm -rf这条命令网上段子最多但现实的残酷程度一点都不减。我的几条切身体会每一条都是真金白银换来的第一写rm -rf时路径宁可多写也不要少写尤其要警惕变量为空的情况。比如脚本里写了rm -rf $DIR/*如果$DIR因为某种原因没取到值这行命令就变成了rm -rf /*后果自己想。稳妥的做法是脚本里先判断变量非空再执行命令前加echo先打印要删除的路径确认无误后再真正执行。第二能用mv代替rm就尽量代替。删除之前先mv file /tmp/trash/把文件挪到回收目录等系统稳定运行几天后再统一清理。这个习惯至少帮我恢复过三次误删场景——以为是废文件删完第二天才发现还有用从/tmp里捞回来就完事。第三实在要用rm删除大量文件时配合find先查后删后面会细讲。1.3 find多条件定位文件比记忆参数更重要find是被严重低估的命令。很多人只会find / -name xxx然后因为权限报错刷屏就放弃了。实际上find最强大的地方在于多条件组合配合-type、-mtime、-size、-exec几乎能解决所有文件定位问题。先列几个高频场景。查找某个目录下30天前没动过的日志文件find /var/log -name *.log -mtime 30-mtime 30表示30天前修改过的文件-mtime -1表示24小时内修改过的文件。这个参数在排查到底哪个文件今天被改过时极其好用。查找超过500M的大文件find / -type f -size 500M-type f限定只找普通文件这能过滤掉大量目录和设备节点减少噪音。同样道理查大目录时用-type d。批量删除找到的文件find /var/log -name *.log -mtime 30 -delete我更推荐先用-exec echo做一次预演确认范围没误伤再把echo换成rm。例如find /var/log -name *.log -mtime 30 -exec echo {} \;执行find时还经常遇到一堆Permission denied报错这是因为用普通用户搜了没有权限的目录。想静默跳过这些目录命令末尾加2/dev/null把错误输出丢掉就行或者干脆用sudo执行。另外find的-name参数是精准匹配文件名想模糊匹配就要用通配符比如*.log。2. 文本处理三件套grep、sed、awk的日常实战姿势2.1 grep过滤日志的正确打开方式排查日志、搜索配置grep绝对是出现频率最高的命令。但多数人只会grep 关键词 文件然后被一堆无关的匹配项淹没。我几乎总是这样用grepgrep -r ERROR /var/log/app/-r递归搜索目录下所有文件适合不知道日志具体在哪个文件里的场景。-i忽略大小写-v反向匹配排除包含指定关键词的行-n输出时带上行号定位问题时直接能看到第几行出错。.log文件非常长只看关键词那一行往往不够需要看上下文。grep -B 3 -A 5 ERROR app.log把错误前3行、后5行的上下文一起打出来这个参数组合排错时几乎必用。还有一个容易被忽略的grep -l只输出文件名不输出匹配的具体内容。在批量搜索多个文件、想知道哪些文件命中了关键词时-l比默认输出好用得多输出干净利落。grep默认支持基础正则想用更复杂的正则时加-E等同于egrep比如匹配多个关键词grep -E ERROR|FATAL|Exception app.log从管道里接收数据是最常用姿势tail -f配合grep实时过滤日志ps配合grep查进程cat配合grep查配置。逻辑很简单前面的命令输出后面的grep负责过滤。2.2 sed流式编辑批量改配置的利器sed像一台文本流水线逐行读取、处理、输出。新手经常踩的第一个坑是用sed s/旧/新/g改完文件打开一看内容没变。因为sed默认把结果输出到屏幕根本不会动原文件。真正要改文件必须加-i参数sed -i s/127.0.0.1/0.0.0.0/g /etc/app.conf-i是原地修改的意思这个参数既有用又危险。我的习惯是执行前先不加-i跑一遍把输出结果核对无误后再加上-i真正执行。批量修改几十台服务器的配置时这个习惯能避免很多低级失误。s是替换命令格式为s/目标/替换值/末尾的g代表全局替换每行所有匹配不加g只替换每行第一处匹配。sed还经常用来查看文件的指定行范围sed -n 20,50p app.log-n是安静模式只输出被处理过的行p是打印。上面的命令会显示第20行到第50行。还有删除空行sed /^$/d file.txt总之sed处理配置文件的批量替换是它最不可替代的场景比如一次性把所有配置里的旧IP换成新IP用编辑器手动改几十个文件容易漏sed -i一行搞定。2.3 awk按列处理数据的瑞士军刀awk比sed更进一步它把每一行按分隔符拆成多个字段按列处理数据。默认分隔符是空格或制表符$0代表整行$1代表第一列$2代表第二列。看一个经典场景从/etc/passwd里提取用户名和用户IDawk -F: {print $1, $3} /etc/passwd-F:指定冒号为分隔符因为passwd文件的字段是用冒号分开的。这个命令的输出就是所有用户名和对应的UID。awk还能做条件筛选。比如从nginx访问日志里统计状态码分布awk {print $9} access.log | sort | uniq -c | sort -rn这条命令我几乎天天用。nginx日志默认用空格分隔第9列是HTTP状态码awk {print $9}把它提取出来sort排序uniq -c计数再sort -rn按数量倒序排列。执行完就能看到200、404、500分别有多少次接口异常一目了然。awk本身是一门完整的编程语言但对日常使用来说掌握字段分割、print输出、简单条件判断就足够了。比如打印请求耗时大于3秒的日志行awk $NF 3 {print $0} app.log$NF表示最后一个字段{print $0}打印整行。可以把它理解成一个按列组合的过滤器。3. 权限与用户管理理解Linux安全模型不要动不动chmod 7773.1 权限位的底层逻辑r、w、x对文件和目录含义完全不同把权限位搞明白是Linux从入门到进阶的一道分水岭。我见过太多人遇到权限问题就chmod 777这等于把门锁拆了问题也确实消失了但安全隐患留了一大堆。权限用数字表示时r4、w2、x1三组权限求和就得到了常见的755、644、600这些数字。关键在于同样的r、w、x作用在文件上和目录上含义完全不同很多人挂在这一点上。对文件来说r表示能查看文件内容w表示能修改内容x表示能当作程序执行。对目录来说r表示能列出目录里有哪些文件名w表示能在目录里创建、删除、重命名文件x表示能进入这个目录cd进去。这里藏着一个非常隐蔽的坑如果一个目录只有w权限没有x权限你既进不去这个目录也无法删除里面的文件。因为删除文件本质是修改目录的内容项需要目录的写权限而进入目录查找需要执行权限。所以给目录授权时要格外注意目录的x权限相当于通行证。对照表权限对文件对目录r(4)查看文件内容列出目录中的文件名w(2)修改文件内容创建/删除/重命名目录中的文件x(1)将文件作为程序执行进入目录3.2 chmod、chown授出权限的正确姿势理解了权限含义再来看改权限的命令。chmod 755 file把文件权限设为属主可读可写可执行、属组和其他人可读可执行。现实中我推荐的安全习惯是普通配置文件644属主可读写其他人只读可执行脚本或目录755属主可读写执行其他人可读执行敏感文件比如私钥、密码文件600仅属主可读写给目录递归授权时用-R参数chmod -R 755 /data/web/但这里有个细节如果目录下既有文件又有子目录统一设成755会把文件也赋予执行权限这倒不是致命问题但不干净。更讲究的做法是用find区分处理find /data/web -type d -exec chmod 755 {} \; find /data/web -type f -exec chmod 644 {} \;这样目录统一755文件统一644既符合规范又能访问。chown用来修改文件的属主和属组格式为chown 用户:组 文件chown -R admin:admin /data/web/-R同样表示递归。我遇到过一种情况网站文件明明是root所有的运行Web服务的用户是www结果www无法写缓存目录页面一直报500。执行chown -R www:www /data/web/cache之后问题立刻消失。所以部署应用时第一件事就要确认目录的属主是不是运行进程的那个用户。3.3 用户与用户组useradd、usermod、passwd的实操要点新建用户是每个Linux使用者都会碰到的基础操作不同发行版的命令表现差异很大。CentOSRHEL系列里useradd和adduser是同一个命令Debian/Ubuntu里adduser是更友好的交互式命令会引导设置密码、创建家目录而useradd默认行为反而不一样。创建用户的推荐写法useradd -m -s /bin/bash zhangsan-m自动创建家目录/home/zhangsan-s指定登录Shell为bash。如果不加-m有些发行版生成的家目录可能不存在用户登录后连工作目录都找不到这是用户建了却进不去的常见原因。把用户加入sudo组、获得管理员权限不同系统写法不同# Debian/Ubuntu usermod -aG sudo zhangsan # CentOS/RHEL usermod -aG wheel zhangsan注意-aG里的-a是追加的意思不加-a会把这个用户从原有的附加组里移除只保留新加的组这个坑我也踩过。修改密码用passwd自己改自己的密码直接执行passwdroot给指定用户重置密码执行passwd zhangsan。忘记密码时用root身份重置不需要原密码。4. 进程与系统状态排查从感觉卡到定位真凶4.1 ps与top进程快照和实时状态怎么配合系统变卡第一反应就是看进程。ps是进程快照top是实时刷新两者互补。ps aux是使用频率最高的组合。注意这里的aux不是某个参数-ef是另一种等价写法。只看进程列表还不够关键是看进程状态列STAT。看到R表示正在运行S是睡眠正常Z是僵尸进程。僵尸进程是父进程没有正确回收子进程资源导致的少量不用管大量堆积就会耗尽系统资源表现为PID持续增长、新进程起不来。top打开后默认按CPU使用率排序按P键按CPU排序、按M键按内存排序这两个键一定要记住。top顶部的load average有三个数字分别代表1分钟、5分钟、15分钟的平均负载。判断负载高低有一个简单标准数值持续大于CPU核心数就说明过载。查看CPU核心数nproc比如CPU是4核load average一直在4以上说明排队等待的任务已经堆积需要进一步确认是哪个进程吃掉了CPU。4.2 kill的学问kill -9不是万能钥匙很多新手杀进程只会kill -9 PID这是很危险的习惯。kill命令默认发送TERM信号信号编号15这是请优雅退出的意思进程收到后可以清理临时文件、关闭句柄、保存数据再退出。而kill -9发送的是KILL信号由内核直接强制杀死进程进程没有任何机会做善后。对数据库、Redis这类需要落盘的服务直接kill -9可能导致数据文件损坏恢复起来非常痛苦。正确的杀进程顺序是# 先找到PID ps -ef | grep 服务名 # 或按进程名直接杀 pkill 服务名 # 等待几秒如果进程还在再用强杀 kill -9 PIDpkill按进程名匹配比手动记PID方便。如果多个同名进程或者命令行里带了特定参数用pkill -f按完整命令行匹配pkill -f python manage.py runserver-f匹配的参数越多误杀的概率越小。4.3 磁盘、内存、负载三个新手最容易误判的指标df -h查磁盘空间这个命令人人会。但磁盘还有一个隐性指标——inode。inode是文件系统存储文件元信息的结构每个文件或目录都要占一个inode。当文件数量过多比如缓存文件、小文件堆积inode耗尽磁盘明明还有空间系统却报No space left on device非常迷惑。查inode使用率df -i看到IUse%接近100%说明inode耗尽需要清理大量小文件。内存用free -h查看。很多人习惯盯着free看发现空闲内存很少就以为内存不足。实际上Linux的内存管理会把空闲内存用作缓存buff/cache加速文件读写这些内存在程序需要时可以释放出来。所以看内存要用available字段它才是真正可用的内存量。排查系统整体压力时vmstat是个好帮手vmstat 1 5每秒打印一次共5次。重点看r列运行队列超过CPU核数说明CPU繁忙、si和so列swap换入换出持续大于0说明内存不足系统在疯狂使用交换分区。这块判断内存还是磁盘瓶颈时很有用。5. 网络排查常用命令从连通性到接口健康的检查顺序5.1 ping、telnet、nc网络到底通不通排查网络问题时我的习惯是从底层往上层逐层检查。ping测试IP层的连通性ping -c 4 目标IP指定发送4个包。但ping通只能说明ICMP可达不代表目标端口开放、服务正常。接下来要测TCP层的连通性。传统方式用telnet 目标IP 端口能连上会显示Connected to连不上就一直卡着直到超时。但telnet测试有个缺点没有明确的退出码在脚本里判断麻烦。更推荐用ncnetcatnc -zv 192.168.1.100 3306-z表示只扫描不发送数据-v输出详细信息-w 3设置超时时间3秒。端口开着会返回open关闭会返回Connection refused。这个命令在脚本里也很好用根据退出码判断端口状态。5.2 ss与netstat查看端口监听和连接状态端口测通了接下来要看本机的端口监听状态。netstat -tlnp是经典命令ss -tlnp是新一代替代品输出更快更准在排查大量连接时尤其明显。ss -tlnp参数含义-t只看TCP-l只看监听状态的端口-n不解析主机名和端口名显示数字-p显示占用端口的进程PID和名称。这个命令解决的核心问题是这个端口到底被谁占着。比如启动服务时提示Address already in use执行一下就知道是什么进程占用了。Linux下TCP连接状态中还经常看到大量TIME_WAIT和CLOSE_WAIT。用ss -s快速看连接状态统计ss -sTIME_WAIT多一般不用操心这是TCP主动关闭连接后的正常状态过一段时间会自动消失。但CLOSE_WAIT多就要警惕了它通常表示程序收到对端关闭连接请求后自身没有正确调用close关闭连接属于代码层面的连接泄漏。这时候就别折腾系统参数了得从业务代码下手。5.3 curl接口自测和故障复现的必备工具排查Web服务的请求问题curl是我的首选。它能模拟HTTP请求把整个交互过程打出来。最基本的几个用法curl -I https://example.com-I只获取响应头200还是404一眼看清。-v输出更详细的交互过程包括DNS解析、SSL握手、请求头、响应头排查接口突然不通时非常有用。判断一个接口的健康状态我常用这套组合curl -s -o /dev/null -w HTTP状态码: %{http_code} 耗时: %{time_total}s\n https://example.com/api/health-s静默模式不显示进度条-o /dev/null把响应体丢弃-w输出自定义信息。执行后直接看到HTTP状态码和总耗时比打开浏览器访问、肉眼观察快了不知道多少倍。配合while循环还能做简单的接口压测和可用性监控。POST接口的测试需要带数据curl -X POST -H Content-Type: application/json -d {name:test} https://example.com/api-X指定请求方法-H添加请求头-d携带请求体。日常联调、复现线上接口问题这一套基本够了。6. 归档压缩与跨机器传输tar、zip、scp、rsync的取舍6.1 tar参数组合不要死记按含义理解tar是Linux下最常用的归档工具。多数人记tar -czvf和tar -xzvf是死记的换个需求就懵了。其实每个字母含义很清晰c创建归档x解压归档z通过gzip压缩/解压v显示处理过程f指定归档文件名后面必须跟文件名所以f永远放在参数最后C解压到指定目录创建压缩包tar -czvf backup.tar.gz /data/www解压到当前目录还是指定目录tar -xzvf backup.tar.gz tar -xzvf backup.tar.gz -C /target/dir注意-C指定解压目标目录这个目录必须提前存在。不解压直接查看压缩包内容tar -tzvf backup.tar.gz这里把c换成t表示列出内容。热搜里频繁出现的linux解压文件乱码多半发生在zip格式的压缩包上tar.gz格式本身没有乱码问题因为tar保留了文件名的原始字节没有额外的编码转换。如果拿到的是zip包而且是从Windows压过来的见下面一节。6.2 zip与unzip跨平台传输的编码细节zip格式在Windows和Linux之间传输乱码是经典老大难问题。根源在于Windows默认用GBK编码保存文件名而Linux默认用UTF-8解压时按UTF-8解析GBK编码的文件名自然全是乱码。解决方式是用unzip指定编码unzip -O CP936 archive.zip-O参数指定解压时的字符编码CP936就是GBK。这样解压出来的文件名基本能正常显示。不是所有版本的unzip都支持-O参数Debian/Ubuntu下的unzip通常可以如果提示参数错误可以考虑安装unar代替它对编码的处理更省心。压缩时为了避免乱码传播我在Linux下对目录打包时优先用tar.gz不用zip。zip虽然和Windows兼容性最好但编码问题太容易踩坑能用tar就用tar。6.3 scp与rsync简单复制和增量同步怎么选服务器之间传文件scp是最简单直接的方式scp /data/app.tar.gz user目标IP:/data/ scp -r /data/www user目标IP:/data/-r递归复制整个目录。scp基于SSH协议安全方面不用担心但它的逻辑是全量复制每次传整个文件同一个文件第二天再传还是全量效率不高。做周期性、重复性的同步时用rsync它只传输差异部分rsync -avz /data/www/ user目标IP:/data/www/参数含义-a归档模式保留权限、时间戳、属主等属性-v显示过程-z传输时压缩数据。第一次执行是全量同步第二次只传变化的部分这在日志备份、代码发布时效率优势非常明显。配合crontab还能实现简单的定时同步。这里有一个我踩过的坑rsync源路径末尾的斜杠有讲究。rsync -avz /data/www/ ...表示同步目录里的内容rsync -avz /data/www ...表示同步这个目录本身。也就是说带斜杠会在目标目录里直接铺开文件不带斜杠会在目标目录里先建一层www目录。中间部署脚本时因为斜杠问题文件层级多套了一层排查半天才意识到是路径末尾的斜杠差异。跨机器传输时另一个实用命令是rsync配合--delete参数让目标目录严格和源目录保持一致源目录删除的文件目标目录也一并删除。但--delete有风险建议先加--dry-run试运行查看会删除哪些文件再真正执行。做运维这行命令记不全很正常man手册永远在那里。真正拉开差距的不是背了多少命令而是知道在什么场景下该用哪条命令、输出结果怎么解读、有哪些隐含的坑。上面这些命令和习惯是我从踩坑中学到的最实用的部分你可以按这个思路把每一条命令都敲一遍再想一想它在你自己的项目里能解决什么问题比单纯收藏一份大全有效得多。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →