30 個 Linux 命令組合:解抉 99% 日常運維需求,新手也能秒上手!

images
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 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 倒序)。
實戰案例
bash
[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 的程序數)。
實戰案例
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 -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。
實戰案例
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 -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 命令)。
實戰案例
bash
[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.日期":給每個文件加日期後綴(雙引號避免文件名含空格時出錯)。
實戰案例
bash
[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)。
實戰案例
bash
[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.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/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/:遠端伺服器的目標目錄。
實戰案例
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.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 欄,需將 !($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 -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 命令(如 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 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);
  • 最後一個 &:將程序放入後台運行。
實戰案例
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.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 埠的監聽情況。
實戰案例
bash
[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 失敗(埠不通),輸出提示資訊。
實戰案例
bash
# 埠通的情況
[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),格式化輸出。
實戰案例
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 -10
120 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/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 權限(避免其他冗餘資訊)。
實戰案例
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 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 條命令。
實戰案例
bash
[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. 按需組合:不用死記硬背,例如「找大文件」就想到 find+du+sort,「分析日誌」就想到 grep+awk+sort,按場景記憶組合邏輯;
  2. 先測後用:批量刪除、修改文件前,先用 ls 或 cat 預覽結果(如將 rm -f 改成 ls -l),避免誤操作;
  3. 善用管道| 是命令組合的核心,將前一個命令的輸出作為後一個命令的輸入,例如「找文件→算大小→排序」就是典型的管道組合;
  4. 記關鍵參數:無需記所有參數,例如 find 記 -name(按名找)、-size(按大小)、-mtime(按時間),awk 記 -F(分隔符)、$n(欄位),满足需求即可。
這些組合雖非「萬能公式」,但能覆蓋 90% 以上的日常运维需求。遇到新場景時,試著用「基礎命令 + 管道 + 過濾」的思路組合,慢慢就能形成自己的运维命令庫。

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top