
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 /$:只查看根分割區(避免顯示其他掛載點),提取使用率和空閒空間。
實戰案例
bash
[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 條結果,避免輸出過長。
實戰案例
bash
[root@web01 ~]# ps -eo pid,ppid,%cpu,%mem,cmd --sort=-%cpu | head -10 PID PPID %CPU %MEM CMD12345 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倒序)。
實戰案例
bash
[root@web01 ~]# find / -type f -size +100M 2>/dev/null | xargs du -sh | sort -hr5.2G /var/log/nginx/access.log # 發現Nginx訪問日誌未切割,佔5.2G800M /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 的程序數)。
實戰案例
bash
[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)。
實戰案例
bash
[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確認網卡名(如 CentOS 7 可能是ens33,非eth0),再替換命令中的網卡名。
6. 組合:w | awk 'NR>1 {print "登錄用戶:"$1" 登錄IP:"$3" 登錄時間:"$4}'
場景說明
懷疑伺服器有非法登錄,需查看「當前在線用戶」,包括用戶名、登錄 IP 和時間,判斷是否有異常賬號。
命令解析
w:查看當前登錄用戶及操作;NR>1:跳過 w 的表頭;$1是用戶名,$3是登錄 IP(本機登錄為localhost),$4是登錄時間。
實戰案例
bash
[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:統計符合條件的行數(即錯誤次數)。
實戰案例
bash
[root@web01 ~]# grep -i "error" /var/log/nginx/error.log | grep -E "2025-09-08" | wc -l128 # 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。
實戰案例
bash
[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」(失敗),標註後輸出。
實戰案例
bash
[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 日誌中異常通常含此關鍵詞)。
實戰案例
bash
[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。
實戰案例
bash
[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 錯誤次數。
實戰案例
bash
[root@web01 ~]# zgrep "timeout" /var/log/nginx/access.log-20250907.gz | wc -l45 # 昨天共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 命令)。
實戰案例
bash
[root@web01 ~]# find /data/backup -name "*.tar.gz" -mtime +7 -exec rm -f {} \;# 執行後,7天前的.tar.gz文件被刪除,可通過ls確認[root@web01 ~]# ls /data/backupbackup_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.日期":給每個文件加日期後綴(雙引號避免文件名含空格時出錯)。
實戰案例
bash
[root@web01 ~]# ls /data/logsaccess.log error.log[root@web01 ~]# for file in /data/logs/*.log; do mv "$file" "$file.$(date +%Y%m%d)"; done[root@web01 ~]# ls /data/logsaccess.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)。
實戰案例
bash
[root@web01 ~]# grep "old_ip" /etc/config/app.confold_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.confold_ip=192.168.1.20 # 已成功替換注意事項
- 若內容含特殊字符(如
/),需用\轉義(例如替換http://old.com為http://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 目錄(避免備份日誌)。
實戰案例
bash
[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/backupapp_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/:遠端伺服器的目標目錄。
實戰案例
bash
[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 中」的行。
實戰案例
bash
[root@web01 ~]# cat /data/blacklist.txt192.168.1.200[root@web01 ~]# cat /data/user.txt2025-09-08 192.168.1.100 user12025-09-08 192.168.1.200 user2 # 黑名單IP2025-09-08 10.0.0.5 user3[root@web01 ~]# awk 'NR==FNR{a[$1];next} !($2 in a)' /data/blacklist.txt /data/user.txt2025-09-08 192.168.1.100 user1 # 過濾掉了黑名單IP的記錄2025-09-08 10.0.0.5 user3注意事項
- 確保兩個文件的 IP 欄位位置正確(如 user.txt 的 IP 若在第 3 欄,需將
!($2 in a)改成!($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 行。
實戰案例
bash
[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 -20Sep 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命令(如 CentOS 6),將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)。
實戰案例
bash
[root@web01 ~]# ps -ef | grep java | grep -v greproot 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);- 最後一個
&:將程序放入後台運行。
實戰案例
bash
[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)。
實戰案例
bash
# 先手動停止app.jar程序[root@web01 ~]# pgrep -f "app.jar" # 無輸出,程序不存在[root@web01 ~]# pgrep -f "app.jar" || /data/app/start.sh2025-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 埠的監聽情況。
實戰案例
bash
[root@web01 ~]# netstat -tulnp | grep :8080tcp6 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 失敗(埠不通),輸出提示資訊。
實戰案例
bash
# 埠通的情況[root@web01 ~]# telnet 192.168.1.200 3306Trying 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 refusedMySQL埠不通 # 輸出提示注意事項
- 若未安裝 telnet,改用
nc -zv 192.168.1.200 3306(z= 只掃描埠,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),格式化輸出。
實戰案例
bash
[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。
實戰案例
bash
[root@web01 ~]# ss -antp | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10120 192.168.1.200 # 該IP有120個連接,若远超其他IP,可能是惡意訪問 30 10.0.0.5 25 203.0.113.8...注意事項
- ss 比 netstat 更快(尤其連接數多時),推薦優先使用;
- 若想限制單個 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:忽略權限不足的報錯。
實戰案例
bash
[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 # 修改為安全權限(所有者讀寫,其他人讀)注意事項
- 若想找「權限含 SUID」的危險文件(可能被提權),用
find / -perm -4000 -type f 2>/dev/null(4000=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 權限(避免其他冗餘資訊)。
實戰案例
bash
[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":排除「從未登錄過」的賬號(減少輸出)。
實戰案例
bash
[root@web01 ~]# lastlog | grep -v "Never logged in"Username Port From Latestroot pts/0 192.168.1.100 Sun Sep 8 10:00:00 +0800 2025admin 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 條命令。
實戰案例
bash
[root@web01 ~]# grep -E "rm -rf|chmod|chown" /root/.bash_history | tail -20rm -rf /data/tmp/* # 正常清理臨時文件chmod 644 /data/app/config.confrm -rf /data/app/logs/old.log # 無異常刪除注意事項
- 命令歷史預設不記錄時間,若想記錄時間,需在
/etc/profile中添加export HISTTIMEFORMAT="%F %T ",執行source /etc/profile生效; - 若用戶手動清空了
.bash_history,此命令無法查詢,需提前配置命令審計(如用 auditd 服務)。
命令組合的核心原則
- 按需組合:不用死記硬背,例如「找大文件」就想到
find+du+sort,「分析日誌」就想到grep+awk+sort,按場景記憶組合邏輯; - 先測後用:批量刪除、修改文件前,先用
ls或cat預覽結果(如將rm -f改成ls -l),避免誤操作; - 善用管道:
|是命令組合的核心,將前一個命令的輸出作為後一個命令的輸入,例如「找文件→算大小→排序」就是典型的管道組合; - 記關鍵參數:無需記所有參數,例如
find記-name(按名找)、-size(按大小)、-mtime(按時間),awk記-F(分隔符)、$n(欄位),满足需求即可。
這些組合雖非「萬能公式」,但能覆蓋 90% 以上的日常运维需求。遇到新場景時,試著用「基礎命令 + 管道 + 過濾」的思路組合,慢慢就能形成自己的运维命令庫。
