1. 定位导航与文件操作:先解决90%的日常使用
1.1 pwd、ls、cd的组合:很多人忽略的基础细节
刚接触Linux的时候,我也有过拿着命令列表死记硬背的阶段,但真正让我把命令用熟的,不是背诵,而是反复在真实环境里敲。先说最常用的三件套:pwd、ls、cd。
pwd(print working directory)用来确认当前所在的绝对路径。很多人觉得它多余,但当你用脚本处理文件路径、或者在多个目录之间跳来跳去的时候,没有它你很快就会迷失方向。举个实操场景:你在/opt/app/logs下面用tail看日志,切到/tmp做临时操作后想回来,靠记忆容易出错,一条pwd就能把锚点钉死。
ls的关键参数,说实话绝大多数新手只用了默认输出,这太浪费了。我日常必用的几个参数组合是:
ls -lh # 以人类可读方式显示文件大小(K/M/G),配合 h 参数一眼看出哪个文件占空间 ls -lt # 按修改时间倒序排列,最新的文件在最上面,排查问题时非常顺手 ls -la # 显示全部文件包含以 . 开头的隐藏配置文件注意,ls -l输出里的第一列那一长串字符,比如drwxr-xr-x,实际上包含了文件类型和权限的两层信息。第一个字符d表示目录,-表示普通文件,l表示软链接;后面每三个字符一组,分别对应属主、属组、其他人的读(r)、写(w)、执行(x)权限。
cd除了进入目录,我最常用的偷懒技巧是cd -——直接回到上一个所在目录。比如你从/etc/nginx/conf.d切到/var/log/nginx看报错,看完想回去改配置,敲一下cd -就够了,不用重新输入一长串路径。这个操作在需要来回对比配置文件和日志的场景下,效率提升非常明显。
1.2 cp、mv、rm:覆盖、备份和"删不掉"的问题
文件操作三兄弟cp、mv、rm,看起来简单,实际踩过的坑一点都不少。
先看cp。复制目录必须加-r,这是最基础的要求:
cp -r /opt/app/config /opt/app/config_backup_20250115这个-r很多人记成 "recursive(递归)",理解到位就不会漏。cp还有几个容易忽略的好用参数:
-i:目标文件已存在时询问是否覆盖,配合alias设置后能防止误覆盖。-p:保留原始文件的属性(权限、时间戳),备份配置文件时特别有用。-a:等效于-dpR,常用于完整复制目录树做归档备份。
我自己的习惯是:只要涉及覆盖操作,就先ls确认目标目录里有什么,再用-i让系统多问一次,避免一年一次的备份把新配置文件冲掉。
再看mv。它有一个隐藏知识点:同一文件系统内移动是"改个指针"级别的瞬时操作,跨文件系统则是"复制+删除"。所以当你把文件从/home移动到/data(两个独立分区)时,如果文件很大,会感觉到明显的耗时,这是正常的物理复制,不是系统卡了。
最后说rm,这是Linux里最需要敬畏的命令。我见过不止一次同事在/tmp下测试命令,一个不留神把变量写空,执行了rm -rf $DIR/*,结果$DIR没赋值,变成rm -rf /*,后果不堪设想。我现在的安全做法是:
# 先对删除目标做一次 ls 确认 ls -la /path/to/target # 删除时带上 -i 或者干脆先移动到临时回收目录 mv /path/to/target /tmp/trash_20250115/把要删的东西先移动到/tmp下的回收目录,观察几天确认没问题再彻底清空,这才是稳妥的操作。生产服务器上永远不要练手速。
2. 文本处理三剑客(grep/sed/awk)的正确打开方式
2.1 grep:从只会搜关键字到熟练组合参数
grep搜索文本几乎是每天必用的命令,但大多数人只会grep error log.txt。它真正的威力在于组合参数,我列几个高频场景:
grep -i "error" /var/log/app.log # 忽略大小写搜索 grep -r "timeout" /opt/app/config/ # 递归搜索目录下所有文件 grep -E "error|warn|fatal" /var/log/app.log # 扩展正则,匹配多个关键词 grep -v "^#" /etc/nginx/nginx.conf # 过滤掉注释行,只看有效配置 grep -c "exception" app.log # 统计匹配到的行数 grep -n "Traceback" app.log # 显示行号,方便回溯新手最容易忽略的是grep -r在搜索日志目录时的输出格式。比如在/var/log/下递归搜索时,结果会带文件路径前缀。如果只关心内容本身,可以加-h去掉文件名;如果想知道每条匹配来自哪个文件,-l只输出文件名列表,配合后续精准查看效率更高。
还有一个心得:搜索日志发现没结果时,先怀疑正则写错,不是故障消失了。有一次我搜ERROR 500,怎么搜都是空,后来发现日志里实际记录的是http_status=500,关键词根本没对上。先用tail -n 50 app.log看一段真实内容格式,再组织搜索词,能省下大量无效排查时间。
2.2 sed:流编辑器里最高频的三个场景
sed被很多人当成"上古神兽"敬而远之,但它真正高频的场景其实只有三个:替换、按行提取、批量删除。
场景一:替换文本
# 把配置里的旧域名换成新地址 sed -i 's/192\.0\.2\.10/192.0.2.20/g' /opt/app/conf/app.confs/旧文本/新文本/g是替换的命令结构,最后的g表示全局替换行内所有匹配,不加它只替换每行第一个。注意点号在正则里是通配符,匹配任意字符,所以匹配IP时要把.转义成\.,否则可能出现意外替换。
场景二:按行号提取
# 查看日志第100到第150行 sed -n '100,150p' app.log-n关闭默认输出,p打印指定范围。这个技巧在日志文件好几GB、cat会卡死的情况下非常实用。
场景三:删除匹配行
# 删除所有包含 DEBUG 的行,且直接写回源文件 sed -i '/DEBUG/d' app.log这里的d是删除命令。-i参数是"直接修改原文件",没有备份习惯时慎用。我自己的规则是:凡是sed -i操作生产配置文件,先手动复制一份.bak,出现问题能秒回滚。这是拿时间换来的教训,早期用sed -i顺手改了个正则,把小半个配置文件洗了,没有备份就只能从头补。
2.3 awk:按列处理数据的入门套路
awk的默认处理单位是"一行按空白分割后的多个字段",这正好覆盖了绝大多数日志和表格类文本的需求。最经典的入门命令:
# 打印第一列和最后一列 awk '{print $1, $NF}' access.log$1是第一列,$NF是最后一列(NF 是字段总数变量)。以Nginx访问日志为例,通常第一列是客户端IP,最后一列是请求耗时,这条命令直接就能产出性能分析源数据。
awk做条件过滤也很顺手:
# 找出请求耗时大于3秒的日志行 awk '$NF > 3 {print $1, $NF}' access.log这里$NF是数值,直接和3比较。再复杂一点,统计访问次数最高的前10个IP:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10这条组合命令的思路很值得讲:awk先抽出第一列的IP,sort排序让相同IP相邻,uniq -c计数并去重,sort -rn按计数反向排序,最后head -10取前十。这个管道组合在日志分析里出现频率极高,建议直接背下来。
3. 权限、用户与进程:从"能跑"到"稳定跑"的分水岭
3.1 chmod、chown、umask:看完这组命令才算入门
权限设置是Linux和Windows体验差异最大的地方,也是新手最容易用"暴力解法"绕过去的地方——我说的就是chmod 777。
数字权限的本质是三组权限的八进制简写。读是4,写是2,执行是1,每组权限的数字就是这三个值相加:
7 = 4+2+1:可读可写可执行6 = 4+2:可读可写5 = 4+1:可读可执行
所以chmod 755 file表示:属主拥有全部权限(7),属组可读可执行(5),其他人可读可执行(5)。而chmod 644 file是:属主可读写(6),属组和其他人只读(4)。普通文件用644、目录用755是通用的安全起点。
遇到"服务起不来"或者"文件写不进去"的问题,正确排查顺序是:
ls -l /path/to/file whoami groups先看文件属于谁、权限是什么,再确认当前用户是谁、在哪个组。多数情况不是权限数字不对,而是属主和属组搞错了,此时要用chown调整归属:
chown -R appuser:appgroup /opt/app/data-R递归修改目录内所有文件和子目录,部署应用或挂载数据目录时几乎必备。
再补充一个容易被忽略的umask。它是"新建文件的默认权限掩码",比如系统umask是022,意思是从默认777里减掉022(组和其他人的写权限),最终新建文件是755;而普通文件中大多数程序会再主动去掉执行位,所以通常是644。搞清楚这个逻辑,就不会遇到"刚创建的脚本没有执行权限"时满脸问号。
3.2 ps、top、kill:现场演示一次完整的进程管理
查进程、看负载、杀进程,这是服务器出问题时最标准的处理链路。
第一步,定位进程:
ps -ef | grep javaps -ef输出所有进程的完整信息,包括UID、PID、PPID、CPU/内存占用、启动命令。配合grep可以快速锁定目标进程。ps aux也是常用写法,两者信息量接近,只是格式侧重不同,aux适合看CPU和内存占比,-ef适合看父进程关系。
第二步,看资源占用:
toptop默认按CPU使用率排序,按M键可以切到按内存排序,按P键回到CPU排序。需要关注的核心指标是%CPU、%MEM、RES(常驻内存)和TIME+(累计CPU时间)。一个进程CPU占用长期超过100%在项目正常波动内可能不算异常,但如果是不该出现的进程,就得注意了。
第三步,处理异常进程:
kill -15 PID # 先温柔地请求退出,让进程自己清理资源 kill -9 PID # 强杀,用于无响应的情况kill不加参数默认发-15(SIGTERM),进程可以拦截并做善后处理。-9(SIGKILL)是强杀,内核直接终止,进程没有机会保存状态。我的习惯是先-15,观察5秒没退出再用-9。直接上-9可能会留下残留的共享内存、临时文件、不完整的数据库写入,后续反而更难收拾。
曾经有一次线上服务内存持续上涨,我ps -ef | grep xxx找到一堆僵尸子进程,PPID已经变成1(被init收养),常规kill都无效。最后排查到是父进程没有正确wait回收子进程,程序逻辑问题,命令行工具只能用来"发现",最终还得靠改代码。
4. 系统状态排查:当机器出问题时该怎么问
4.1 df、du、free:三句话摸清磁盘和内存
服务器响应慢、服务异常退出,第一步永远是检查资源水位,而不是急着看代码。df、du、free三条命令能在半分钟内给出一份基础体检报告。
df -hT-h人类可读,-T显示文件系统类型。重点关注/和/home、/data这类挂载点的Use%,超过80%就进入预警区间。磁盘满时有个经典现象:程序还在正常运行,但写日志报No space left on device。
有个排查细节特别容易迷惑人:df显示占用100%,但du -sh /*怎么加都加不满。这通常是有文件被删除但进程仍然持有文件句柄——文件在磁盘上的空间没有真正释放,只有重启对应进程才会回收。定位方式是:
lsof | grep deleted找到持有被删文件的PID,确认无误后重启该服务,空间才能释放。知道这个坑之后,处理"磁盘满了但找不到大文件"的问题就轻松多了。
free -h看内存时,重点不是free那一列,而是available。Linux会把空闲内存拿去做buff/cache(缓存磁盘数据),真正可用的内存要看available,它是"可以直接分配给新进程"的内存估算值。如果available经常低于总内存的20%,说明内存偏紧,下一步就该用top排序看谁在吃内存了。
4.2 uname、uptime、dmesg:快速了解这台机器的"身体状况"
接手一台陌生的机器,我先用三条命令建立对它的大致认知:
uname -a输出内核版本、主机名、硬件架构。它能立刻告诉你系统是64位还是32位、内核是什么版本,安装软件时选择对应包就需要这些信息。
uptime这条命令输出当前时间、运行时长、登录用户数、以及过去1分钟、5分钟、15分钟的平均负载。负载这个数字容易被误读:它不等于CPU使用率,而是"处于运行或不可中断状态的进程数量"。判断是否过载要看负载和CPU核数的比例——四核机器负载持续超过4.0,基本可以认为CPU是瓶颈了。
dmesg -T | tail -50dmesg显示内核环形缓冲区的消息,-T把时间戳转成可读格式。硬件报错、磁盘I/O错误、OOM(内存耗尽)记录、网络设备异常,基本都能在这里看到痕迹。如果某天应用程序莫名其妙崩溃,来dmesg翻一翻,经常能看到Out of memory: Kill process这类关键线索。
5. 网络排查与文件传输:从本地到远程的常用操作
5.1 ping、curl、ss:一套连贯的网络诊断流程
网络问题排查我很少吃"一条命令定生死"的亏,而是固定走一套流程。先看三层,再看七层。
第一步:ping 测连通性
ping -c 4 192.0.2.10-c 4只发四个包就停,避免一直ping停不下来。观察time值判断延迟,观察packet loss判断丢包率。ping 通只能说明三层网络通,不能代表应用可用——服务没起来照样能ping通。
第二步:curl 验证应用层
curl -I http://192.0.2.10:8080/health-I只取响应头,比完整拉取正文更轻量。如果返回200 OK那说明服务正常,返回502或504就要往上游排查(比如网关后面的应用没启动)。
第三步:ss 查看端口监听状态
ss -tulnp-tTCP协议,-uUDP协议,-l只显示监听状态,-n不解析服务名只显示端口数字,-p显示占用进程。这台机器上哪些端口在监听、由哪个进程占用,一眼就能看出来。替换掉早期习惯用的netstat,ss更快信息也更全。
5.2 scp、rsync:文件传输的取舍
小文件传输用scp简单直接:
scp /opt/app/backup_20250115.tar.gz appuser@192.0.2.20:/data/backup/本地文件推送到远端,或者反过来拉取都可以。但要传输大量文件、或者做定期同步,rsync是更好的选择,它的核心优势是增量同步——只传变化的部分。我备份目录的习惯命令:
rsync -avz --progress /opt/app/data/ appuser@192.0.2.20:/data/backup/data/参数拆解:-a归档模式保留权限和时间戳,-v显示过程,-z传输时压缩,--progress显示进度。
用rsync有一个必须注意的经典细节:源路径末尾的斜杠决定行为。rsync -av /path/a/ /path/b/表示把a目录下的内容同步到b目录;但rsync -av /path/a /path/b/会把a目录本身放到b里面,变成b/a/。很多时候同步完发现层级多了一层,就是这个斜杠在捣鬼,我复盘时发现几乎每个团队都有人被它坑过。
6. Shell小技巧组合:把单个命令拼成真正的生产力
6.1 管道、重定向与逻辑符号:理解Shell的执行思维
单个命令只是零件,Shell真正的威力在于把它们拼起来。我先讲透几个符号的本质区别。
管道|:把左边命令的标准输出接到右边命令的标准输入。ps -ef | grep nginx就是把进程列表喂给grep做过滤。管道处理的是数据流,不是文件,所以左右两侧命令同时运行。
重定向>和>>:>把输出写到文件并覆盖原内容,>>追加到文件末尾。标准错误(stderr)和标准输出(stdout)是不同的通道,只写>只能捕获stdout,报错信息经常还是会出现在屏幕上。如果想把两者都存进同一个文件:
command > run.log 2>&12>&1的含义是"把文件描述符2(标准错误)重定向到文件描述符1(标准输出)当前指向的位置"。这个写法从我开始用Linux到现在,出现的频率高到几乎每天都会敲一次。如果懒得解释原理,直接背下来当固定搭配也行。
逻辑符号&&和;:&&表示前一条命令成功了才执行后一条,适合串联依赖步骤。;则不管前一条成不成功都会执行后一条,适合"无论如何都要做的收尾工作"。
6.2 history与alias:把重复敲击变成一次回车
每个Linux重度用户都有自己的一套alias配置,这能让重复性工作变得轻快很多。我在~/.bashrc里的几组典型配置:
alias ll='ls -lh' alias la='ls -la' alias grep='grep --color=auto' alias df='df -hT' alias rm='rm -i'第四行rm='rm -i'是我自觉加上的保险,删除时系统多问一次,误删概率大幅下降。
history配合快捷键的效率提升也常被低估。history看完整记录,!4321直接重跑第4321条历史命令,Ctrl+R反向搜索历史命令——输入几个关键字回车直接调出之前的长命令,比翻聊天记录找命令快多了。
6.3 几条日常高频的组合命令:拿来就能用
分享几条我几乎每天都要用到的组合命令,它们不是小众技巧,而是经历过真实场景验证的效率工具。
# 查看实时日志,只看最新追加的内容 tail -f /var/log/app/app.log # 在日志中查找某个关键词并实时跟踪 tail -f /var/log/app/app.log | grep "ERROR" # 找出当前目录下最大的10个文件或目录 du -ah --max-depth=1 . | sort -hr | head -10 # 查看某个端口的连接状态,确认是否有异常连接 ss -tan | awk '{print $1}' | sort | uniq -c # 压缩打包某个目录,排除指定的缓存目录 tar czf backup.tar.gz --exclude='cache' --exclude='tmp' /opt/app/data第一条tail -f是排查问题的第一利器,任何日志往后翻、持续观察新内容,都靠它。第二条组合是在日志量非常大的情况下,只输出匹配ERROR的行,避免满屏刷屏看花眼。
最后说一句压箱底的经验:命令不是背出来的,是查出来的。真正重要的不是记住了多少个命令,而是知道"有这么一个东西可以实现这个效果",记不清具体语法时随时man 命令名或者命令名 --help现场查。用得多了,自然就变成肌肉记忆了。
就我个人而言,把这些组合命令写进脚本和alias之后,日常操作的效率提升了不止一个量级。如果你现在还在逐条敲命令,不妨先从今天提到的几条开始尝试——挑一两个场景,把它们真正用起来,比一次性抄走全部技巧更有价值。