☰
Linux高频命令实战:从环境检查到日志排障的运维手册
2026/10/7 10:34:12 网站建设 项目流程

初接手一台不熟悉的服务器,心跳通常会加速半拍。环境变量对不对、服务有没有起来、日志在哪写、磁盘还剩多少,这些问题不摸清楚,后面每一步都像踩在棉花上。Linux的诱惑和门槛恰好都在同一个地方:一切皆文件、一切可脚本化,但前提是你得知道那些高频命令怎么用、为什么这样用,以及组合起来之后能达到什么效果。这篇文章不打算做命令大全式的罗列,而是把我在实际工作中最常用、最顺手的那批命令按场景拆开揉碎,附上排查思路和踩过的坑,给正在补Linux基础、准备上生产环境的同学一份可以直接照做的实操手册。

1. 第一件事:先看清自己手上的环境

进到一台机器,别急着敲命令。我先花一分钟确认系统、内核、运行时间、资源情况,这四样东西决定后面所有操作怎么落地。

1.1 系统信息与内核识别

cat /etc/os-release uname -a uptime

/etc/os-release是几乎所有主流发行版都会提供的文件,里面直接写了发行版名称和版本号,比如CentOS Stream、Ubuntu 22.04,或者Debian。读这个文件比用lsb_release -a更通用,因为某些精简安装的系统里可能没有lsb_release这个命令。

uname -a输出内核版本和硬件架构,x86_64代表64位,aarch64是ARM64。这决定了你下载的二进制包、编译参数、内核模块能不能对上号。我记得有一次在ARM服务器上直接复制了x86版本的JDK压缩包,解压后一执行就报Exec format error,检查uname -m才发现架构从一开始就没对上。

uptime不只是看开机时间,它的输出里包含load average 1/5/15分钟三个数值,这是判断机器当前有无压力的第一道信号。单核机器load超过2基本就是在硬扛了,但如果load高而CPU空闲,通常说明有大量的不可中断IO在等待,常见源头是磁盘慢或NFS卡住。

1.2 内存和磁盘现状检查

free -h df -h

free -h用易读单位展示物理内存和交换分区。注意看available列,这是真正可用的内存评估值,它已经把page cache的回收空间算进去了,比盯着free列靠谱得多。系统刚启动时free列很小、buff/cache列很大,这是正常现象,说明内存被缓存利用起来了,别慌。

df -h看文件系统挂载与使用率。使用率到80%就可以考虑清理,到95%基本就是随时会出事的状态。生产环境我还会习惯性追一条df -i看inode,因为大量小文件会先耗尽inode,导致磁盘明明有空间却报No space left on device,这种问题光看df -h是发现不了的。

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

工作里真正的日常不是装软件、配服务,而是处理日志、提取字段、批量改配置。这三条命令用的频率远远高于其他一切工具,值得把每个常用参数和基本逻辑都吃透。

2.1 grep:日志排查的放大镜

grep -r "ERROR" /var/log/nginx/error.log grep -i "timeout" app.log | grep -v "health" grep -E "2025-03-.*500" access.log

grep的常用搭档是-r递归、-i忽略大小写、-v反向匹配、-E启用扩展正则。实际排查里最出效果的是先大范围抓关键字,再用管道二次过滤,一层层把噪音剥掉。比如想看某天所有接口的500错误,一条grep -E "23/Mar/2025.* 500 " access.log就能精准定位到秒。

我给新人的建议是:能用grep别用cat。很多初学者习惯先cat整个文件再慢慢找,日志一大了直接刷屏,还会把终端拖慢。直接grep让工具替你找,快且干净。加--color=auto高亮命中部分,或者干脆设置alias让grep默认带上这个参数。

2.2 awk:字段提取与统计

grep负责定位行,awk负责处理行里的字段和统计。它的默认用法是按空白符切分,$1代表第一个字段,$0代表整行。举个例子,nginx的access.log里,第9列通常是响应时间(单位毫秒),想找出超过3秒的慢请求:

awk '$9 > 3000 {print $1, $7, $9}' access.log

这一行命令能快速列出来源IP、请求路径和响应时间,在性能排查里属于最快出头的三板斧之一。awk还能干简单的统计,比如统计每个IP的访问次数:

awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log | sort -k2 -rn | head -20

它的语法看起来有点像C语言,但不熟练的话不需要全背,记住字段分割、BEGIN/END、数组累加这三个常用套路,就能覆盖绝大多数日志统计场景。

2.3 sed:原地批量替换

sed -i 's/old_string/new_string/g' config.conf

sed的-i是直接修改文件,不要在生产环境里对不知道内容的文件贸然使用。s是替换命令,g是全局替换标记,不加g的话一行内只替换第一处。坑点在于sed默认按行处理,如果配置项是跨行的多行结构,直接s///会失效,这时候要么调整文件结构,要么用perl来做多行模式匹配。

另一个实用玩法是删除指定行,比如批量去掉配置文件里所有注释和空行:

sed -i '/^#/d;/^$/d' config.conf

d表示删除匹配的行。这个操作在整理一份被注释段扰乱视野的配置时非常好用,我也常用它做配置文件瘦身,只留下有效项再看逻辑。

3. 进程与性能排查:定位CPU被打满的完整链路

服务器响应慢、CPU飙高是每个运维和开发者都会遇到的事。这套排查链路我总结下来特别固定,顺序执行基本不会漏。

3.1 top:第一眼看到什么才不算白看

top

top默认按CPU占用从高到低排序。第一屏的信息量大,别只盯着进程列表。看负载平均值判断整体压力,看us/sy两个CPU时间占比判断是用户进程消耗还是内核消耗。sy占比过高时,常见原因包括系统调用频繁(比如大量小数据包读写)、锁竞争、或者驱动异常。

按P按CPU排序,按M按内存排序,按1展开每个CPU核心的负载分布。如果多核心里只有某几个核心高,大概率是单线程程序卡在某个任务上,而不是整体过载。

3.2 定位进程与线程

top里看到吃CPU的PID后,要搞清楚这个进程到底在干什么。先看进程的启动参数和完整路径:

ps -ef | grep <PID> ls -l /proc/<PID>/cwd cat /proc/<PID>/cmdline | tr '\0' ' '

/proc/<PID>/cwd是符号链接,指向进程当前工作目录;cmdline里的参数用\0分隔,加上tr '\0' ' '可以把它们转成空格分隔,阅读起来更舒服。这几个命令能快速判断是Java进程、Nginx worker,还是某个shell脚本的子进程。

线程级的分析用top -H -p <PID>,可以看到进程内部每个线程的CPU消耗。Java应用卡顿时候,常能看到某一个线程占满一个核,再结合jstack导出线程栈,就能定位到具体业务代码那一段逻辑。

3.3 端口与连接排障

端口被占用或者端口不通,是更常见的日常烦恼。ss命令已经替代了老旧的netstat,更好用、更快:

ss -tlnp ss -tnp | grep :8080

-t看TCP,-l看监听态,-n不做DNS解析,-p显示进程信息。第一条命令能看到当前哪些端口在监听、对应哪个进程;第二条能看某个端口的所有TCP连接,包括ESTABLISHED、TIME_WAIT等状态。排查连接数异常时,可以数一下TIME_WAIT状态的数量,太多的话就要考虑是不是短连接频繁建立、没有开启连接复用。

lsof这个命令也值得留在工具箱里。lsof -i :8080能看到谁在连这个端口,lsof | grep deleted能列出那些被进程持有、但已经被删除的日志文件。后者是个隐蔽的磁盘空间隐患,因为文件被删除但进程还在写,文件句柄仍然持有空间,df看起来空间没释放,真正的排查点却在进程身上。

4. 文件查找与磁盘清理:从定位大文件到安全释放空间

4.1 find:按条件构建查找任务

find /var/log -name "*.log" -mtime +7 -size +100M find / -type f -size +2G -exec ls -lh {} \;

find的参数设计得非常口语化,-name按文件名,-mtime按修改时间(单位是天),-size按文件体积,-type f限定为普通文件。第一行找大于100MB且7天前修改的日志,是典型的清理候选集。第二行在全盘找超过2GB的大文件,适合排查磁盘空间突然被吃掉的场景。

find里的-exec和{} \;是固定组合,意思是把前面找到的每个文件路径逐一代入{},执行ls -lh。注意最后的\;不能写成;,shell里的分号是有特殊含义的,必须转义。

4.2 du与df的配合

判断一个目录到底占了多少空间:

du -sh /var/lib/docker du -sh /* 2>/dev/null | sort -rh | head -10

-s总结目录总大小,-h人类可读,第二条命令用sort -rh按体积倒序排列,能快速挑出盘子里的“大胃王”。docker的overlay2目录经常在不经意间长到几十GB,养成定期du -sh的习惯非常有用。

删除文件还要留个心眼。如果发现删除文件后空间没有释放,赶紧去查进程是否有文件句柄挂在被删文件上:

lsof +L1

这个命令能列出所有被标记为deleted但仍被进程持有的文件,找到对应的进程后,重启服务或让进程重新打开文件句柄,空间才会真正释放。

4.3 压缩与远程传输

日志清理时,别一股脑删,有时候需要留底。tar是最好的朋友:

tar -czf logs-$(date +%Y%m%d).tar.gz /var/log/nginx

-c创建归档,-z用gzip压缩,-f指定输出文件名。$(date +%Y%m%d)动态生成日期后缀,比如logs-20250310.tar.gz。今后想解压查看时用tar -xzf即可。跨服务器转移文件常用rsync,它能做增量同步,只传变化的部分:

rsync -avz --progress /local/data/ user@remote:/remote/backup/

-a归档模式保留权限和属性,-v显示进度,-z压缩传输。首次做全量同步后,后续只传增量,对带宽极其友好。注意目标路径结尾的斜杠语义:/remote/backup/表示把data目录里的内容放进backup目录,去掉斜杠则会把data目录本身放进去,弄反了目录层级会错乱。

5. 后台运行与定时任务:让脚本在无人盯守时也靠谱

5.1 nohup与后台执行

在终端直接启动一个长时间任务,关掉窗口后进程就没了,这是触达后台运行概念的经典场景。解决办法是nohup:

nohup python3 process_data.py > run.log 2>&1 &

nohup让进程忽略挂断信号,> run.log 2>&1把标准输出和标准错误都重定向到同一个日志文件,最后的&让任务在后台运行。这样终端窗口可以放心关掉,进程继续跑。查看任务日志:tail -f run.log。要杀掉它,需要先找到PID:ps -ef | grep process_data.py或者pgrep -f process_data.py。

用&挂后台的方式适合一次性任务,但不适合需要开机自启、异常恢复的服务。那种场景应该用systemd,把长任务注册成service,配好Restart=on-failure,崩溃后会自动拉起,比nohup稳妥得多。

5.2 systemctl服务管理

systemctl start my-service systemctl enable my-service systemctl status my-service journalctl -u my-service -f

start和enable的区别要知道:start是立刻启动,enable是设置开机自启。新写一个服务单元文件丢进/etc/systemd/system/my-service.service,直接能用。journalctl -u my-service看的是这个服务的系统日志,-f实时跟踪,排查服务启动失败比翻/var/log/messages高效得多。

Ordering和依赖关系在多个服务之间需要编排时才有用,日常单服务用不到,但Restart=always和WorkingDirectory这两个字段我建议务必配置好,前者保证异常退出后自动恢复,后者让服务在指定目录下启动,避免相对路径踩坑。

5.3 crontab定时任务

定时任务的基础通了之后,细节才是真正的分水岭:

crontab -e # 每分钟检查一次服务存活 * * * * * /root/scripts/check_nginx.sh >> /var/log/check_nginx.log 2>&1

crontab里一个常见的心理学陷阱是:新人的脚本习惯性只写脚本路径,以环境变量没加载为由,脚本里命令找不到。解决办法是在脚本首行固定写#!/bin/bash,并在脚本内显式export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,让环境先干净起来,再去执行真正的任务逻辑。

写定时任务时,还要注意两点:时间规范代表分、时、日、月、周;2>&1必须有,否则脚本出错时没有任何日志留下,排查失败就全靠猜了。另外脚本里如果用了date之类的命令,建议指定完整路径,比如/bin/date,避免因PATH问题拿到不同结果。

6. 网络排查三板斧:ping、telnet、traceroute的合理分工

6.1 ping是ICMP的探针,不是端口检查器

ping -c 4 10.0.0.1

ping走的是ICMP协议,它只回答“这台机器通不通”,不能回答“这个端口通不通”。两台主机之间ICMP通,不代表业务端口通,因为防火墙可以开放ping、却禁止TCP 443。新人排查时习惯先ping,这是起步动作,但别停在这个结论上。

6.2 telnet测端口连通的直观笨办法

telnet 192.168.1.10 3306

连上了,会进入一个连接成功的空窗口;连不上,立刻报Connection refused或者超时。这是验证某IP某端口是否放行的最原始、也最有效的笨办法。生产环境不想装telnet,用bash内置的/dev/tcp也行:

timeout 3 bash -c 'echo > /dev/tcp/192.168.1.10/3306' && echo "port is open"

timeout 3防止连不上的时候一直卡住。这个方式不需要额外装任何包,脚本里做端口健康检查特别好使。

6.3 traceroute定位网络断裂点

traceroute -n 8.8.8.8

-n不做域名解析,只显示IP,速度更快。输出里每一跳代表经过的一个路由器节点,如果连续几个节点都是* * *,说明包在该段丢失或防火墙封禁。跨云、跨机房访问异常时,traceroute能帮你划清责任范围:是本地网关问题,还是中间运营商节点,抑或对端防火墙。

我自己排查时通常的节奏是:ping确认主机存活状态,telnet确认端口监听与防火墙放行情况,traceroute确认整条链路有没有“黑洞”。三步走完,问题出在哪一段基本就清楚了。

7. 提升效率的小习惯:alias、history与脚本化思维

7.1 alias:给常用长命令起个短名

alias ll='ls -lh --color=auto' alias df='df -h' alias du='du -sh' alias grep='grep --color=auto'

写进/etc/profile.d/myalias.sh或~/.bashrc里,新开终端自动生效。这些alias能让常规操作省掉大量重复输入,还能避免漏参数(比如df不加-h,输出的块数统计读起来非常累)。注意alias在非交互式shell里默认不生效,所以别指望它出现在crontab脚本里。

7.2 history:命令回溯与复用

history !42 Ctrl+R

history列出历史命令,!42重新执行编号42的命令,Ctrl+R进入反向搜索、敲关键字自动匹配历史记录。改坏配置前的上一个正确命令、查过的进程号、上次用的grep语法,都能从history里捞回来。给新人一个实用建议:调试命令行的时候,每次操作都记得自己敲一遍、不要依赖自动补全的旧命令,避免因为参数变更导致引用了过时命令。

7.3 一个脚本化的日常巡检示例

与其每天手动敲命令,不如把固定动作封成一个bash脚本:

#!/bin/bash # daily health check echo "=== Disk usage ===" df -h echo "=== Mem info ===" free -h echo "=== Load average ===" uptime echo "=== Top 5 CPU consumers ===" ps aux --sort=-%cpu | head -6

把这段脚本存成healthcheck.sh,chmod +x healthcheck.sh,之后每次上机器先跑一遍,基础状态一眼扫完。脚本化不是为了炫技,是为了把脑力和时间留给真正需要判断的问题,而不是花两分钟敲无脑命令。

8. 权限与用户管理的几个硬核边界

8.1 chmod与chown

chmod 755 script.sh chown -R appuser:appgroup /opt/app

755代表所有者读写执行、组读执行、其他人读执行。这对脚本、程序目录是稳妥的权限方案。chown -R递归修改目录属主和属组,部署应用包之后务必注意,别把目录交给了错误的用户。实践里的一个高频错误是:用root解压了应用包,导致所有文件属主都是root,应用以普通用户运行起来时无法写自己的日志或临时文件。

文件权限还有一种情况要看懂:setuid/setgid位。例如/usr/bin/sudo是一个带setuid的文件,普通用户执行它时会临时获得root权限。这属于Linux权限模型里的特殊能力,查ls -l /usr/bin/sudo会看到属主的执行权限位是s而非x。

8.2 useradd与用户管理

useradd -m -s /bin/bash ops passwd ops usermod -aG wheel ops

-m创建用户主目录,-s指定登录shell,passwd设置密码,usermod -aG把用户加入附加组。常见发行版里wheel组成员默认可以通过sudo提权。新用户如果发现自己sudo报“不在sudoers中”,多半就是少了这步。

删除用户不要直接rm -rf /home/user,那是暴力做法。正规方式是userdel -r username,-r连带删除主目录和mail spool。如果用户还在跑着服务进程,记得先停进程再删用户,避免遗留一堆僵尸进程和文件属主为已删除UID的混乱状态。

9. 日志查看的姿势:tail、head、less、journalctl

日志不只是排障才看,日常工作里养成“打开服务前先开日志窗口”的习惯,能省很多事后排查的时间。

9.1 tail与head配合

tail -n 100 app.log tail -f app.log head -50 app.log

-n指定行数,-f跟随模式,文件末尾追加内容时实时输出。启动一个服务后,同时开一个tail -f并做一次操作,是最快的验证路径。head一般不常用,但要看日志文件最开始的启动信息时,它是唯一顺手的工具。日志滚动导致的tail -f失效是常见问题,需要配合--follow=name参数看待滚动后的新文件。

9.2 less与搜索

less -N app.log /ERROR n q

less打开大日志文件再按/输入目标关键字,n跳到下一个匹配,q退出。它不会像cat一样把整个文件倒进终端,大文件也能顺畅浏览。多学一个操作:G跳到文件末尾、g跳到开头,这在查看启动日志和最新日志时很好使。

journald日志配合systemd服务有天然的对应关系。journalctl -u service-name --since "1 hour ago"直接看过去一小时的日志,不用去猜滚动文件的位置,这比翻/var/log下的零散文件省心得多。


实际操作里用得久了,我越来越觉得Linux命令不是背出来的,是用出来的。刚入门时先反复玩熟grep、awk、sed和find这几把刀,遇到真实问题再查手册、看man page,比通读一本几百页的命令词典高效得多。翻车几次之后就会形成自己的排查肌肉记忆——看日志先tail后grep,看到CPU高先top再ps,查端口先ss再telnet,这套动作稳了,你就能在生产环境立住脚了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询