30 个 Linux 命令组合:解决 99% 日常运维需求,看完就能用!

2025-09-09 09:23:17 RAIZ

 

Linux 运维的核心效率,从来不是 “背会多少单个命令”,而是 “能把命令组合起来解决实际问题”。比如磁盘满了要快速找大文件、系统卡了要定位高负载进程、日志报错要提取关键数据 —— 这些场景靠单个命令根本不够,必须靠 “命令组合” 破局。

下面 30 个组合,按 “系统监控、日志分析、文件管理、进程管理、网络排查、权限审计”6 大高频场景分类,每个组合都来自真实运维场景,附带具体操作案例,新手也能直接复制使用。

一、系统监控与资源排查类(6 个):快速定位资源瓶颈

日常运维中,“系统负载高”“磁盘满”“内存不够用” 是最常见的告警,这 6 个组合能帮你 1 分钟找到问题根源。

1. 组合:top -b -n 1 | grep Cpu | awk '{print "CPU使用率:"$2"%"}' && free -h | grep Mem | awk '{print "内存使用率:"$3"/"$2"("$7"空闲)"}' && df -h | grep /$ | awk '{print "根分区使用率:"$5"("$4"空闲)"}'

场景说明

刚登录服务器,想快速看 CPU、内存、根分区的核心状态,不用分别输 top、free、df 三个命令。

命令解析

  • • top -b -n 1:非交互模式输出 1 次系统状态,避免进入 top 交互界面;
  • • grep Cpu:过滤 CPU 行,awk提取使用率;
  • • free -h:人性化显示内存,grep Mem聚焦内存行;
  • • df -h | grep /$:只看根分区(避免显示其他挂载点),提取使用率和空闲空间。

实战案例

\[root@web01 \~]# top -b -n 1 | grep Cpu | awk '{print "CPU使用率:"\$2"%"}' && free -h | grep Mem | awk '{print "内存使用率:"\$3"/"\$2"("\$7"空闲)"}' && df -h | grep /\$ | awk '{print "根分区使用率:"\$5"("\$4"空闲)"}'

CPU使用率:12.3%

内存使用率:1.2Gi/7.7Gi(6.3Gi空闲)

根分区使用率:45%(50G空闲)

注意事项

  • • 若根分区挂载点不是/(比如特殊系统),需把grep /$改成实际挂载点(如grep /root)。

2. 组合:ps -eo pid,ppid,%cpu,%mem,cmd --sort=-%cpu | head -10

场景说明

系统 CPU 使用率突然飙升到 80% 以上,要快速找出 “吃 CPU 最多的前 10 个进程”,看是不是异常进程(如挖矿程序)。

命令解析

  • • ps -eo:自定义输出字段(pid = 进程 ID,ppid = 父进程 ID,% cpu=CPU 占比,% mem = 内存占比,cmd = 进程命令);
  • • --sort=-%cpu:按 CPU 占比倒序排列(-表示倒序);
  • • head -10:只显示前 10 条,避免输出过长。

实战案例

\[root@web01 \~]# ps -eo pid,ppid,%cpu,%mem,cmd --sort=-%cpu | head -10

  PID  PPID %CPU %MEM CMD

12345     1 35.2  8.5 /usr/bin/java -jar app.jar  # 发现Java进程占CPU最高

12367 12345 12.1  2.3 /usr/bin/python3 monitor.py

...

注意事项

  • • 若想查 “吃内存最多” 的进程,把--sort=-%cpu改成--sort=-%mem

3. 组合:find / -type f -size +100M 2>/dev/null | xargs du -sh | sort -hr

场景说明

收到 “根分区使用率 90%” 的告警,要快速找到 “大于 100M 的大文件”,看是不是日志没切割或临时文件没清理。

命令解析

  • • find / -type f -size +100M:从根目录找所有大小超过 100M 的文件(-type f指定文件,避免目录);
  • • 2>/dev/null:忽略权限不足的报错(比如/proc目录下的文件);
  • • xargs du -sh:对找到的文件逐个计算大小(-s单文件,-h人性化显示);
  • • sort -hr:按大小倒序排列(-h识别 “G/M” 单位,-r倒序)。

实战案例

\[root@web01 \~]# find / -type f -size +100M 2>/dev/null | xargs du -sh | sort -hr

5.2G    /var/log/nginx/access.log  # 发现Nginx访问日志没切割,占5.2G

800M    /tmp/large\_file.tar.gz

...

注意事项

  • • 若想找 “大于 1G” 的文件,把+100M改成+1G
  • • 删除大文件前先确认用途(比如access.log若在使用,需先切割再删除)。

4. 组合:vmstat 1 5 | awk 'NR>1 {print "平均等待IO时间:"$16"ms 等待IO进程数:"$17"个"}'

场景说明

系统响应变慢,但 CPU、内存使用率都不高,怀疑是 “磁盘 IO 瓶颈”,要查看 IO 等待情况。

命令解析

  • • vmstat 1 5:每 1 秒输出 1 次系统 IO 状态,共输出 5 次(避免单次数据不准);
  • • NR>1:跳过 vmstat 的表头行;
  • • $16:vmstat 输出中 “wa” 字段(IO 等待时间,单位 ms),$17:“st” 字段(等待 IO 的进程数)。

实战案例

\[root@web01 \~]# vmstat 1 5 | awk 'NR>1 {print "平均等待IO时间:"\$16"ms  等待IO进程数:"\$17"个"}'

平均等待IO时间:2ms  等待IO进程数:0个

平均等待IO时间:3ms  等待IO进程数:0个

...  # 若wa持续超过10ms,说明IO有瓶颈

注意事项

  • • 若 wa 长期超过 20ms,需进一步用iostat -x 1查看具体磁盘的 IO 情况(如sda的 util% 是否接近 100%)。

5. 组合:sar -n DEV 1 3 | grep -v Average | awk '/eth0/ {print "网卡eth0:接收"$5"KB/s 发送"$6"KB/s"}'

场景说明

服务器带宽跑满,要查看 “指定网卡(如 eth0)的实时流量”,判断是接收还是发送流量过高。

命令解析

  • • sar -n DEV 1 3:每 1 秒输出 1 次网卡流量,共 3 次(-n DEV指定网卡统计);
  • • grep -v Average:排除最后一行的平均值(只看实时数据);
  • • awk '/eth0/:只过滤 eth0 网卡的行,$5是接收流量(rxkB/s),$6是发送流量(txkB/s)。

实战案例

\[root@web01 \~]# sar -n DEV 1 3 | grep -v Average | awk '/eth0/ {print "网卡eth0:接收"\$5"KB/s  发送"\$6"KB/s"}'

网卡eth0:接收1200KB/s  发送300KB/s

网卡eth0:接收1350KB/s  发送280KB/s

...  # 若接收流量持续超过10000KB/s(约100Mbps),可能是被攻击

注意事项

  • • 先通过ip addr确认网卡名(如 centos7 可能是ens33,不是eth0),再替换命令中的网卡名。

6. 组合:w | awk 'NR>1 {print "登录用户:"$1" 登录IP:"$3" 登录时间:"$4}'

场景说明

怀疑服务器有非法登录,要查看 “当前在线的用户”,包括用户名、登录 IP 和时间,判断是否有异常账号。

命令解析

  • • w:查看当前登录用户及操作;
  • • NR>1:跳过 w 的表头;
  • • $1是用户名,$3是登录 IP(若本地登录是localhost),$4是登录时间。

实战案例

\[root@web01 \~]# w | awk 'NR>1 {print "登录用户:"\$1"  登录IP:"\$3"  登录时间:"\$4}'

登录用户:root  登录IP:192.168.1.100  登录时间:10:23

登录用户:admin  登录IP:10.0.0.5  登录时间:11:05  # 若IP不在信任列表,需排查

注意事项

  • • 若想查 “历史登录记录”,改用last -n 10(显示最近 10 次登录)。

二、日志分析与数据提取类(6 个):从海量日志中抓关键信息

运维中 80% 的问题排查要靠日志,但日志动辄几百 MB,靠 “逐行看” 根本不现实,这 6 个组合能帮你快速提取有用数据。

7. 组合:grep -i "error" /var/log/nginx/error.log | grep -E "2025-09-08" | wc -l

场景说明

Nginx 服务报 500 错误,要统计 “9 月 8 日当天的 error 日志条数”,判断错误是偶尔出现还是持续爆发。

命令解析

  • • grep -i "error":忽略大小写找含 “error” 的行(避免漏 “Error”“ERROR”);
  • • grep -E "2025-09-08":用正则匹配指定日期(日志需带时间戳,Nginx 默认日志格式含日期);
  • • wc -l:统计符合条件的行数(即错误次数)。

实战案例

\[root@web01 \~]# grep -i "error" /var/log/nginx/error.log | grep -E "2025-09-08" | wc -l

128  # 9月8日共128条错误日志,需进一步看具体错误

注意事项

  • • 若日志时间格式是 “09/Sep/2025”,需把日期改成"08/Sep/2025"(对应 Nginx 的%d/%b/%Y格式)。

8. 组合:grep "500" /var/log/nginx/access.log | awk '{print $1,$7,$9}' | sort | uniq -c | sort -nr | head -10

场景说明

监控显示 “Nginx 500 错误率上升”,要找出 “出现 500 错误最多的前 10 个 IP 和 URL”,判断是单个 IP 异常访问还是特定接口有问题。

命令解析

  • • grep "500":过滤状态码为 500 的请求($9是 Nginx 日志的状态码字段);
  • • awk '{print $1,$7,$9}':提取 IP($1)、URL($7)、状态码($9);
  • • sort | uniq -c:按 “IP+URL” 去重并统计次数(uniq -c计数);
  • • sort -nr:按次数倒序,head -10取前 10。

实战案例

\[root@web01 \~]# grep "500" /var/log/nginx/access.log | awk '{print \$1,\$7,\$9}' | sort | uniq -c | sort -nr | head -10

  23 192.168.1.200 /api/pay 500  # 该IP访问支付接口500错误23次

  18 10.0.0.8 /api/order 500

...

注意事项

  • • 需确认 Nginx 日志格式:若自定义格式中 IP 不是$1、URL 不是$7,需调整awk的字段序号(可先head -1 access.log看日志结构)。

9. 组合:tail -f /var/log/messages | grep --line-buffered "ssh" | awk '/Accepted/ {print "正常登录:"$0} /Failed/ {print "登录失败:"$0}'

场景说明

想 “实时监控 SSH 登录情况”,一旦有成功登录或失败尝试,立即在终端显示,方便及时发现暴力破解。

命令解析

  • • tail -f:实时跟踪日志文件(新内容会自动输出);
  • • grep --line-buffered "ssh":缓冲每行内容(避免实时输出延迟),过滤含 “ssh” 的行;
  • • awk:区分 “Accepted”(成功登录)和 “Failed”(失败),标注后输出。

实战案例

\[root@web01 \~]# tail -f /var/log/messages | grep --line-buffered "ssh" | awk '/Accepted/ {print "正常登录:"\$0} /Failed/ {print "登录失败:"\$0}'

正常登录:Sep  8 14:30:01 web01 sshd\[12345]: Accepted password for root from 192.168.1.100 port 5678 ssh2

登录失败:Sep  8 14:32:05 web01 sshd\[12367]: Failed password for root from 203.0.113.5 port 1234 ssh2  # 陌生IP尝试登录,需拦截

注意事项

  • • 部分系统 SSH 日志在/var/log/secure,需把/var/log/messages改成对应路径。

10. 组合:sed -n '/2025-09-08 14:00:00/,/2025-09-08 14:30:00/p' /var/log/tomcat/catalina.out | grep "Exception"

场景说明

开发反馈 “9 月 8 日 14:00-14:30 之间 Tomcat 报异常”,要提取 “这个时间段内的所有 Exception 日志”,快速定位代码问题。

命令解析

  • • sed -n '/开始时间/,/结束时间/p':提取两个时间戳之间的日志(-n静默模式,p打印匹配内容);
  • • grep "Exception":过滤含 “Exception” 的异常行(Java 日志中异常通常含此关键词)。

实战案例

\[root@web01 \~]# sed -n '/2025-09-08 14:00:00/,/2025-09-08 14:30:00/p' /var/log/tomcat/catalina.out | grep "Exception"

2025-09-08 14:15:23 ERROR \[http-nio-8080-exec-5] com.xxx.service.UserService: NullPointer Exception at line 123  # 找到空指针异常

注意事项

  • • 日志时间格式必须和sed中的匹配(比如含空格、冒号的位置),否则提取不到内容;
  • • 若时间段内日志太多,可加head -100先看前 100 行,避免输出过长。

11. 组合:awk -F '|' '{print $3}' /var/log/app/log.txt | sort | uniq -c | sort -nr | head -5

场景说明

应用日志用 “|” 分隔字段(如 “时间 | 用户 ID | 接口名 | 耗时”),要统计 “调用次数最多的前 5 个接口”,分析业务热点。

命令解析

  • • awk -F '|':指定字段分隔符为 “|”(默认是空格);
  • • print $3:提取第 3 个字段(即接口名);
  • • sort | uniq -c:去重并统计次数,sort -nr倒序,head -5取前 5。

实战案例

\[root@web01 \~]# awk -F '|' '{print \$3}' /var/log/app/log.txt | sort | uniq -c | sort -nr | head -5

  1256 /api/user/login  # 登录接口调用最多,符合业务预期

   890 /api/user/info

   678 /api/order/list

...

注意事项

  • • 先通过head -1 log.txt确认字段分隔符和接口名所在的字段序号(比如分隔符是 “,”,就把-F '|'改成-F ',')。

12. 组合:zgrep "timeout" /var/log/nginx/access.log-20250907.gz | wc -l

场景说明

要分析 “昨天压缩后的 Nginx 日志”(后缀.gz)中 “timeout 错误的次数”,不用先解压再 grep(节省磁盘空间)。

命令解析

  • • zgrep:直接 grep 压缩文件(支持.gz 格式),避免gunzip解压步骤;
  • • wc -l:统计 timeout 错误次数。

实战案例

\[root@web01 \~]# zgrep "timeout" /var/log/nginx/access.log-20250907.gz | wc -l

45  # 昨天共45次timeout错误

注意事项

  • • 若压缩格式是.bz2,改用bzgrep;若想同时查多个压缩文件,用zgrep "timeout" access.log-202509*.gz

三、文件管理与批量操作类(6 个):告别重复手动操作

运维中常遇到 “批量改文件名”“批量替换文件内容”“批量传输文件” 等需求,手动做 10 个文件还好,100 个就崩溃了,这 6 个组合能帮你自动化处理。

13. 组合:find /data/backup -name "*.tar.gz" -mtime +7 -exec rm -f {} \;

场景说明

/data/backup 目录下有每天的备份文件(如 backup_20250901.tar.gz),要 “删除 7 天前的旧备份”,避免占满磁盘。

命令解析

  • • find /data/backup:指定查找目录;
  • • -name "*.tar.gz":只找后缀为.tar.gz 的文件;
  • • -mtime +7:修改时间超过 7 天(+7表示 7 天前,-7是 7 天内);
  • • -exec rm -f {} \;:对找到的文件执行删除操作({}代表找到的文件,\;结束 exec 命令)。

实战案例

\[root@web01 \~]# find /data/backup -name "\*.tar.gz" -mtime +7 -exec rm -f {} \\;

\# 执行后,7天前的.tar.gz文件被删除,可通过ls确认

\[root@web01 \~]# ls /data/backup

backup\_20250902.tar.gz  backup\_20250908.tar.gz  # 只剩7天内的文件

注意事项

  • • 首次执行前,建议把rm -f改成ls -l(先查看要删除的文件,确认无误再删),避免误删;
  • • 若想按 “访问时间” 删除,把-mtime改成-atime

14. 组合:for file in /data/logs/*.log; do mv "$file" "$file.$(date +%Y%m%d)"; done

场景说明

每天凌晨要 “给 /data/logs 目录下的所有.log 文件加日期后缀”(如 access.log→access.log.20250908),方便后续归档。

命令解析

  • • for file in /data/logs/*.log:循环遍历所有.log 文件;
  • • date +%Y%m%d:生成当前日期(如 20250908);
  • • mv "$file" "$file.日期":给每个文件加日期后缀(双引号避免文件名含空格时出错)。

实战案例

\[root@web01 \~]# ls /data/logs

access.log  error.log

\[root@web01 \~]# for file in /data/logs/\*.log; do mv "\$file" "\$file.\$(date +%Y%m%d)"; done

\[root@web01 \~]# ls /data/logs

access.log.20250908  error.log.20250908

注意事项

  • • 若想加 “年月日时分”(如 202509081430),把date +%Y%m%d改成date +%Y%m%d%H%M

15. 组合:sed -i 's/old_ip=192.168.1.10/old_ip=192.168.1.20/g' /etc/config/*.conf

场景说明

要 “批量修改 /etc/config 目录下所有.conf 文件中的 IP”(把 192.168.1.10 改成 192.168.1.20),不用逐个打开文件编辑。

命令解析

  • • sed -i:直接修改文件内容(-i原地替换,不加-i只预览不修改);
  • • s/旧内容/新内容/g:替换语法(s=substitute,g=global 全局替换,避免只换第一处);
  • • /etc/config/*.conf:指定要修改的文件(所有.conf)。

实战案例

\[root@web01 \~]# grep "old\_ip" /etc/config/app.conf

old\_ip=192.168.1.10

\[root@web01 \~]# sed -i 's/old\_ip=192.168.1.10/old\_ip=192.168.1.20/g' /etc/config/\*.conf

\[root@web01 \~]# grep "old\_ip" /etc/config/app.conf

old\_ip=192.168.1.20  # 已成功替换

注意事项

  • • 若内容含特殊字符(如/),需用\转义(比如替换http://old.comhttp://new.com,命令是s/http:\/\/old.com/http:\/\/new.com/g);
  • • 先在 1 个文件上测试(如sed -i.bak 's/...' app.conf,生成.bak 备份文件),确认无误再批量修改。

16. 组合:tar -zcvf /data/backup/app_$(date +%Y%m%d).tar.gz /data/app --exclude=/data/app/logs

场景说明

备份 /data/app 目录时,要 “排除 logs 子目录”(日志占空间且无需备份),并给备份包加日期后缀,方便识别。

命令解析

  • • tar -zcvf:打包压缩(z用 gzip 压缩,c创建包,v显示过程,f指定包名);
  • • app_$(date +%Y%m%d).tar.gz:备份包名含日期;
  • • --exclude=/data/app/logs:排除 logs 目录(避免备份日志)。

实战案例

\[root@web01 \~]# tar -zcvf /data/backup/app\_20250908.tar.gz /data/app --exclude=/data/app/logs

/data/app/

/data/app/config/

/data/app/bin/  # 未包含logs目录

...

\[root@web01 \~]# ls /data/backup

app\_20250908.tar.gz

注意事项

  • • 若要排除多个目录,加多个--exclude(如--exclude=logs --exclude=tmp);
  • • 备份前确认目标目录空间足够(可用df -h /data/backup查看)。

17. 组合:scp -r /data/backup/*.tar.gz root@192.168.1.200:/data/remote_backup/

场景说明

要 “把本地 /data/backup 目录下的所有.tar.gz 备份包,批量传输到远程服务器 192.168.1.200 的 /data/remote_backup 目录”,实现异地备份。

命令解析

  • • scp -r:远程拷贝(-r递归拷贝目录,这里虽拷贝文件,但加-r不影响,且支持后续拷贝目录);
  • • root@192.168.1.200:远程服务器用户名和 IP;
  • • :/data/remote_backup/:远程服务器的目标目录。

实战案例

\[root@web01 \~]# scp -r /data/backup/\*.tar.gz root@192.168.1.200:/data/remote\_backup/

root@192.168.1.200's password:  # 输入远程服务器密码

app\_20250908.tar.gz  100%  500MB  100MB/s   00:05  # 传输完成

注意事项

  • • 若想免密码传输,需配置 SSH 密钥对(ssh-keygen生成密钥,ssh-copy-id root@192.168.1.200分发公钥);
  • • 大文件传输建议用rsync(支持断点续传),命令是rsync -avz /data/backup/*.tar.gz root@192.168.1.200:/data/remote_backup/

18. 组合:awk 'NR==FNR{a[$1];next} !($2 in a)' /data/blacklist.txt /data/user.txt

场景说明

/data/blacklist.txt 是 “黑名单 IP 列表”(每行一个 IP),/data/user.txt 是 “用户访问记录”(格式 “时间 IP 用户名”),要 “提取不在黑名单中的用户记录”,过滤异常 IP。

命令解析

  • • NR==FNR:NR 是总行数,FNR 是当前文件行数,此条件只对第一个文件(blacklist.txt)生效;
  • • a[$1]:把黑名单 IP 存到数组 a 中;
  • • next:跳过后续处理,继续读下一行;
  • • !($2 in a):对第二个文件(user.txt),只打印 “IP($2)不在数组 a 中” 的行。

实战案例

\[root@web01 \~]# cat /data/blacklist.txt

192.168.1.200

\[root@web01 \~]# cat /data/user.txt

2025-09-08 192.168.1.100 user1

2025-09-08 192.168.1.200 user2  # 黑名单IP

2025-09-08 10.0.0.5 user3

\[root@web01 \~]# awk 'NR==FNR{a\[\$1];next} !(\$2 in a)' /data/blacklist.txt /data/user.txt

2025-09-08 192.168.1.100 user1  # 过滤掉了黑名单IP的记录

2025-09-08 10.0.0.5 user3

注意事项

  • • 确保两个文件的 IP 字段位置正确(如 user.txt 的 IP 是3 则改!($3 in a))。

四、进程与服务管理类(4 个):快速管控服务状态

运维中 “启动 / 停止服务”“查看服务日志”“重启异常进程” 是日常操作,这 4 个组合能帮你更高效地管理进程和服务。

19. 组合:systemctl status nginx | grep -E "active|inactive|failed" && journalctl -u nginx --since "10 minutes ago" | tail -20

场景说明

要 “快速查看 Nginx 服务状态”(是运行中、停止还是失败),并看 “最近 10 分钟的服务日志”,判断服务是否正常。

命令解析

  • • systemctl status nginx:查看 Nginx 服务状态;
  • • grep -E "active|inactive|failed":只显示核心状态(active = 运行中,inactive = 停止,failed = 失败);
  • • journalctl -u nginx:查看 Nginx 的系统日志(-u指定服务单元);
  • • --since "10 minutes ago":只看最近 10 分钟的日志,tail -20取最后 20 行。

实战案例

\[root@web01 \~]# systemctl status nginx | grep -E "active|inactive|failed"

   Active: active (running) since Sun 2025-09-08 10:00:00 CST; 4h ago  # 服务正常运行

\[root@web01 \~]# journalctl -u nginx --since "10 minutes ago" | tail -20

Sep 08 14:20:01 web01 nginx\[1234]: 192.168.1.100 - - \[08/Sep/2025:14:20:01 +0800] "GET / HTTP/1.1" 200 1234 "-" "Chrome/116.0.0.0"

...  # 最近10分钟日志无异常

注意事项

  • • 若系统用service命令(如 centos6),把systemctl status nginx改成service nginx status,日志路径改用/var/log/nginx/error.log

20. 组合:ps -ef | grep java | grep -v grep | awk '{print $2}' | xargs kill -9

场景说明

Java 进程异常卡死(用jps看不到进程,但ps能看到),要 “强制杀死所有 Java 进程”,之后重启服务。

命令解析

  • • ps -ef | grep java:找所有含 “java” 的进程;
  • • grep -v grep:排除 “grep java” 这个临时进程(避免误杀);
  • • awk '{print $2}':提取进程 ID($2 是 ps -ef 输出的 PID 字段);
  • • xargs kill -9:对提取的 PID 执行强制杀死(kill -9是强制终止,kill -15是正常终止,卡死时用-9)。

实战案例

\[root@web01 \~]# ps -ef | grep java | grep -v grep

root     12345     1  0 10:00 ?        00:01:23 /usr/bin/java -jar app.jar

\[root@web01 \~]# ps -ef | grep java | grep -v grep | awk '{print \$2}' | xargs kill -9

\[root@web01 \~]# ps -ef | grep java | grep -v grep  # 已无Java进程

注意事项

  • • 此命令会杀死所有 Java 进程,若服务器有多个 Java 服务(如 Tomcat、Jenkins),需加更精准的过滤(如grep "app.jar"只杀指定进程),避免误杀其他服务。

21. 组合:nohup /data/app/start.sh > /data/logs/app.log 2>&1 &

场景说明

要 “后台启动 /data/app/start.sh 脚本”,并把输出日志写到 /data/logs/app.log,且退出终端后进程不停止(避免终端关闭导致进程退出)。

命令解析

  • • nohup:忽略挂断信号(no hang up),终端退出后进程继续运行;
  • • > /data/logs/app.log:把标准输出(stdout,脚本的正常输出)重定向到 app.log;
  • • 2>&1:把标准错误(stderr,脚本的错误输出)也重定向到 stdout(即一起写入 app.log);
  • • 最后一个&:把进程放到后台运行。

实战案例

\[root@web01 \~]# nohup /data/app/start.sh > /data/logs/app.log 2>&1 &

\[1] 12345  # 后台进程ID

\[root@web01 \~]# tail -f /data/logs/app.log  # 查看启动日志

2025-09-08 14:30:00 应用启动中...

2025-09-08 14:30:05 应用启动成功!

注意事项

  • • 确保/data/logs目录存在(不存在则先mkdir -p /data/logs),否则会报错;
  • • 查看后台进程用jobs(当前终端)或ps -ef | grep start.sh(任意终端)。

22. 组合:pgrep -f "app.jar" || /data/app/start.sh

场景说明

写定时任务(crontab)时,要 “检查 app.jar 进程是否存在,不存在则启动”,实现服务的简单保活(避免服务意外退出后无人处理)。

命令解析

  • • pgrep -f "app.jar":根据进程名(-f匹配完整命令行)查找进程,找到返回 PID,找不到返回非 0 状态码;
  • • ||:逻辑或,只有前面命令失败(进程不存在)时,才执行后面的启动命令(/data/app/start.sh)。

实战案例

\# 先手动停止app.jar进程

\[root@web01 \~]# pgrep -f "app.jar"  # 无输出,进程不存在

\[root@web01 \~]# pgrep -f "app.jar" || /data/app/start.sh

2025-09-08 14:35:00 应用启动中...

2025-09-08 14:35:05 应用启动成功!  # 进程不存在,执行启动

\# 再次检查

\[root@web01 \~]# pgrep -f "app.jar"

12345  # 进程已存在,不执行启动

注意事项

  • • 若要加日志,把启动命令改成nohup /data/app/start.sh > /data/logs/app.log 2>&1 &(结合前面的后台启动组合);
  • • 定时任务配置(crontab -e):每 5 分钟检查一次,*/5 * * * * pgrep -f "app.jar" || nohup /data/app/start.sh > /data/logs/app.log 2>&1 &

五、网络连接与故障排查类(4 个):快速定位网络问题

运维中 “服务连不上”“访问超时”“端口不通” 是常见网络问题,这 4 个组合能帮你快速排查是服务器、端口还是网络链路的问题。

23. 组合:netstat -tulnp | grep :8080

场景说明

Tomcat 服务启动后,要 “检查 8080 端口是否被监听”,判断服务是否真的启动成功(避免服务启动报错但没察觉)。

命令解析

  • • netstat -tulnp:查看所有监听端口(t=TCP,u=UDP,l= 监听中,n= 显示 IP 和端口(非服务名),p= 显示进程 ID 和名称);
  • • grep :8080:过滤 8080 端口的监听情况。

实战案例

\[root@web01 \~]# netstat -tulnp | grep :8080

tcp6       0      0 :::8080                 :::\*                    LISTEN      12345/java  # 8080端口被Java进程(Tomcat)监听,启动成功

注意事项

  • • 部分系统默认没有 netstat,需先安装(centos:yum install net-tools,ubuntu:apt install net-tools);
  • • 若想查所有端口,去掉grep :8080,用netstat -tulnp | sort -n -k4按端口号排序。

24. 组合:telnet 192.168.1.200 3306 || echo "MySQL端口不通"

场景说明

Web 服务器连不上 MySQL 服务器(192.168.1.200:3306),要 “测试 MySQL 端口是否能通”,判断是 MySQL 服务没启动还是防火墙拦截。

命令解析

  • • telnet 目标IP 端口:测试 TCP 端口连通性;
  • • || echo "...":若 telnet 失败(端口不通),输出提示信息。

实战案例

\# 端口通的情况

\[root@web01 \~]# telnet 192.168.1.200 3306

Trying 192.168.1.200...

Connected to 192.168.1.200.  # 连接成功,端口通

Escape character is '^]'.

\# 端口不通的情况

\[root@web01 \~]# telnet 192.168.1.200 3306 || echo "MySQL端口不通"

Trying 192.168.1.200...

telnet: connect to address 192.168.1.200: Connection refused

MySQL端口不通  # 输出提示

注意事项

  • • 若没安装 telnet,改用nc -zv 192.168.1.200 3306z= 只扫描端口,v= 显示详细信息);
  • • 端口不通时,先在 MySQL 服务器上用netstat -tulnp | grep 3306看服务是否启动,再查防火墙(firewall-cmd --list-ports)是否开放 3306。

25. 组合:traceroute 10.0.0.1 | grep -E "^\s*[0-9]+" | awk '{print "跳数:"$1" IP:"$2" 延迟:"$3}'

场景说明

服务器访问 10.0.0.1(总部网关)超时,要 “跟踪网络链路”,看是哪一跳(路由器)出了问题,延迟过高还是丢包。

命令解析

  • • traceroute 目标IP:跟踪从本地到目标 IP 的所有网络节点(跳数);
  • • grep -E "^\s*[0-9]+":过滤含跳数的行(避免开头的注释行);
  • • awk:提取跳数($1)、节点 IP($2)、延迟($3),格式化输出。

实战案例

\[root@web01 \~]# traceroute 10.0.0.1 | grep -E "^\s\*\[0-9]+" | awk '{print "跳数:"\$1"  IP:"\$2"  延迟:"\$3}'

跳数:1  IP:192.168.1.1  延迟:1.243ms

跳数:2  IP:10.0.0.1  延迟:5.678ms  # 两跳到达,无延迟过高

\# 若某跳显示“\* \* \*”,说明该节点丢包,需排查对应路由器

注意事项

  • • 部分系统没安装 traceroute,需安装(centos:yum install traceroute,ubuntu:apt install traceroute);
  • • 若目标 IP 禁 ping,traceroute 可能显示不全,改用traceroute -T 目标IP(用 TCP 探测)。

26. 组合:ss -antp | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10

场景说明

Nginx 服务(80 端口)的连接数突然飙升,要 “找出连接 80 端口最多的前 10 个 IP”,判断是否有 IP 在恶意发起大量连接(如 CC 攻击)。

命令解析

  • • ss -antp:查看所有 TCP 连接(a= 所有,n= 显示 IP 端口,t=TCP,p= 显示进程);
  • • grep :80:过滤 80 端口的连接;
  • • awk '{print $5}':提取客户端 IP 和端口($5是 ss 输出的 “客户端地址:端口” 字段);
  • • cut -d: -f1:按 “:” 分割,取 IP 部分(去掉端口);
  • • sort | uniq -c:统计每个 IP 的连接数,sort -nr倒序,head -10取前 10。

实战案例

\[root@web01 \~]# ss -antp | grep :80 | awk '{print \$5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10

  120 192.168.1.200  # 该IP有120个连接,若远超其他IP,可能是恶意访问

   30 10.0.0.5

   25 203.0.113.8

...

注意事项

  • • ss 比 netstat 更快(尤其连接数多时),推荐优先用 ss;
  • • 若想限制单个 IP 的连接数,可在 Nginx 配置中加limit_conn_zone $binary_remote_addr zone=perip:10m;limit_conn perip 50;(单 IP 最多 50 个连接)。

六、权限与安全审计类(4 个):保障服务器安全

运维中 “权限配置错误导致服务起不来”“误删文件”“非法修改配置” 是常见安全问题,这 4 个组合能帮你审计权限和操作记录。

27. 组合:find /data/app -perm 777 -type f 2>/dev/null

场景说明

服务器被扫描出 “有文件权限为 777(所有人可读写执行)”,要 “找出 /data/app 目录下所有权限为 777 的文件”,修改为安全权限(如 644)。

命令解析

  • • find /data/app:指定查找目录;
  • • -perm 777:只找权限为 777 的文件(777=rwxrwxrwx);
  • • -type f:只找文件(避免目录,目录 777 风险较低);
  • • 2>/dev/null:忽略权限不足的报错。

实战案例

\[root@web01 \~]# find /data/app -perm 777 -type f 2>/dev/null

/data/app/config/db.conf  # 发现配置文件权限为777,有安全风险

\[root@web01 \~]# chmod 644 /data/app/config/db.conf  # 修改为安全权限( owner读写,其他读)

注意事项

  • • 若想找 “权限含 SUID” 的危险文件(可能被提权),用find / -perm -4000 -type f 2>/dev/null4000=SUID 位);
  • • 不要盲目把所有 777 文件改成 644,需确认文件用途(如脚本文件可能需要执行权限,改 755)。

28. 组合:getfacl /data/app | grep -E "user:|group:"

场景说明

ls -l看 /data/app 目录权限是drwxr-xr-x,但某个用户还是没权限访问,要 “查看该目录的 ACL(访问控制列表)权限”,判断是否有特殊权限配置。

命令解析

  • • getfacl /data/app:查看目录的 ACL 权限(比ls -l更详细,支持多用户 / 组权限);
  • • grep -E "user:|group:":只显示用户和组的 ACL 权限(避免其他冗余信息)。

实战案例

\[root@web01 \~]# getfacl /data/app | grep -E "user:|group:"

user::rwx  # 所有者权限

user:admin:r-x  # admin用户有读执行权限

group::r-x  # 所属组权限

group:dev:---  # dev组无权限(可能是问题原因)

注意事项

  • • 若要给用户加 ACL 权限,用setfacl -m u:admin:rwx /data/app(给 admin 用户加读写执行权限);
  • • 查看文件 ACL 权限同理,把目录改成文件路径(如getfacl /data/app/config.conf)。

29. 组合:lastlog | grep -v "Never logged in"

场景说明

要 “查看所有用户的最后登录时间”,判断是否有长期不用的账号被非法登录(比如 root 账号 3 个月没登录,突然有登录记录)。

命令解析

  • • lastlog:显示所有用户的最后登录信息(包括系统账号);
  • • grep -v "Never logged in":排除 “从未登录过” 的账号(减少输出)。

实战案例

\[root@web01 \~]# lastlog | grep -v "Never logged in"

Username         Port     From             Latest

root             pts/0    192.168.1.100    Sun Sep  8 10:00:00 +0800 2025

admin            pts/1    10.0.0.5         Sun Sep  8 11:05:00 +0800 2025

注意事项

  • • lastlog显示的是/var/log/lastlog文件的内容,若该文件被清空,会显示不准确;
  • • 若想查 “某个用户的登录记录”,用lastlog -u admin(查看 admin 用户)。

30. 组合:grep -E "rm -rf|chmod|chown" /root/.bash_history | tail -20

场景说明

服务器上的文件突然丢失,要 “查看 root 用户最近执行的 20 条含 rm -rf、chmod、chown 的命令”,判断是否有人误操作删除文件或修改权限。

命令解析

  • • grep -E "rm -rf|chmod|chown":过滤含危险命令(rm -rf 删除,chmod 改权限,chown 改所有者)的行;
  • • /root/.bash_history:root 用户的命令历史文件(普通用户是/home/用户名/.bash_history);
  • • tail -20:显示最后 20 条命令。

实战案例

\[root@web01 \~]# grep -E "rm -rf|chmod|chown" /root/.bash\_history | tail -20

rm -rf /data/tmp/\*  # 正常清理临时文件

chmod 644 /data/app/config.conf

rm -rf /data/app/logs/old.log  # 无异常删除

注意事项

  • • 命令历史默认不记录时间,若想记录时间,需在/etc/profile中加export HISTTIMEFORMAT="%F %T ",执行source /etc/profile生效;
  • • 若用户手动清空了.bash_history,此命令无法查到,需提前配置命令审计(如用 auditd 服务)。

命令组合的核心原则

  1. 1. 按需组合:不要死记硬背,比如 “找大文件” 就想到find+du+sort,“分析日志” 就想到grep+awk+sort,按场景记组合逻辑;
  2. 2. 先测后用:批量删除、修改文件前,先用lscat预览结果(比如把rm -f改成ls -l),避免误操作;
  3. 3. 善用管道|是命令组合的核心,把前一个命令的输出作为后一个命令的输入,比如 “找文件→算大小→排序” 就是典型的管道组合;
  4. 4. 记关键参数:不用记所有参数,比如find-name(按名找)、-size(按大小)、-mtime(按时间),awk-F(分隔符)、$n(字段),够用就行。

这些组合不是 “万能公式”,但能覆盖你 90% 以上的日常运维需求。遇到新场景时,试着用 “基础命令 + 管道 + 过滤” 的思路组合,慢慢就能形成自己的运维命令库。

 

我要咨询