:從文本處理到磁盤管理的高頻命令詳解)
1. 為什么學Linux總卡在“會用但不懂”很多人學Linux都有一個共同的困惑命令背了一堆跟著教程敲了一遍當時覺得全會了過幾天再碰又覺得手生。我也經(jīng)歷過這個階段而且時間不短。直到后來做了一次系統(tǒng)性的實戰(zhàn)整理把零散的知識點串成一條線才發(fā)現(xiàn)問題不在記性而在學習方式。這套“小柏實戰(zhàn)學習Linux”系列就是圍繞真實操作場景來組織的。每一篇都從實際需求出發(fā)先搞清楚“要解決什么問題”再一步步落地命令和配置。這一篇是第八講重點聚焦在文本處理、進程管理、網(wǎng)絡排查和磁盤操作這四個方向。這些內(nèi)容看起來基礎但恰恰是日常使用頻率最高、最容易出錯的環(huán)節(jié)。如果你已經(jīng)在用Linux但總覺得命令是死記硬背、換個環(huán)境就發(fā)蒙這一篇可以幫你把思路理清楚。如果你剛入門跟著實操走一遍也能避開不少我當年踩過的坑。2. 四個高頻場景為什么值得花時間拆解2.1 文本處理日志排查和配置修改的日常功課Linux系統(tǒng)里幾乎所有配置都是文本文件日志也是文本。所以文本處理能力直接決定了你排查問題的效率。很多新手只會用cat把文件全打出來日志一大就刷屏根本看不過來。真正干活的時候需要的是精確抽取、過濾、統(tǒng)計和格式化輸出。這篇里的文本處理部分用的是awk、sed、grep、sort、uniq這幾個命令的組合拳。它們各自負責一件事串聯(lián)起來就能完成從“原始日志”到“結論”的完整鏈路。2.2 進程管理系統(tǒng)卡頓和異常排查的入口服務器卡了、CPU飆高了、某個服務掛了第一件事就是看進程。ps只能看靜態(tài)快照top能實時刷新配合kill、nice、renice這些控制命令才能完整管理一個進程的整個生命周期。我在實操中特別加了按線程維度排查CPU占用的小例子因為生產(chǎn)環(huán)境里很多性能問題都藏在多線程進程的某個線程里只看進程級數(shù)據(jù)往往定位不到根因。2.3 網(wǎng)絡排查服務連不上的時候靠它救命網(wǎng)絡問題是最讓人頭疼的。域名解析對不對、端口通不通、數(shù)據(jù)包丟沒丟、路由怎么走的每層問題都需要不同工具。ping和telnet只能做最初步的連通性測試真正深入還得靠ss、traceroute、tcpdump這些工具。2.4 磁盤操作從分區(qū)到掛載的完整流程磁盤操作屬于平時用不到、一旦要用就容錯率很低的操作。分區(qū)表、文件系統(tǒng)、掛載點每一步都有講究。這篇的disk案例里我完整走了一遍“識別磁盤-分區(qū)-格式化-掛載-驗證”的流程并且特別強調(diào)了數(shù)據(jù)備份的問題。場景涉及命令典型痛點文本處理awk、sed、grep、sort、uniq日志太大、格式不統(tǒng)一進程管理ps、top、kill、nice、reniceCPU飆高、找不到進程網(wǎng)絡排查ping、ss、traceroute、tcpdump端口不通、連接超時磁盤操作lsblk、fdisk、mkfs、mount分區(qū)誤操作、掛載失敗這四個場景有一個共同特點都離不開“觀察-定位-動手-驗證”的循環(huán)。觀察靠查看類命令定位靠過濾和分析動手靠控制類命令驗證靠再次查看。理解了這條循環(huán)遇到新工具也能快速上手。3. 文本處理三件套grep、awk、sed的配合實戰(zhàn)3.1 grep先篩行快速劃定范圍grep的核心邏輯是按行匹配模式把符合條件的行打印出來。排查日志時第一步永遠是先用grep把相關行撈出來縮小范圍。假設有一個名為“app.log”的日志文件里面有大量訪問記錄和錯誤信息。最常見的操作是:grep ERROR app.log這只是最簡單的用法。實際排查中更常用的是加參數(shù)grep -n ERROR app.log # 顯示行號 grep -i error app.log # 忽略大小寫 grep -v DEBUG app.log # 反向匹配排除調(diào)試日志這里有個很容易忽略的點如果日志文件很大比如幾個GB直接用grep全量掃描會慢。可以先按時間段粗篩比如日志名按日期滾動類似app-20250601.log這樣的命名或者在日志里先截取某個時間窗口后再繼續(xù)處理。實際生產(chǎn)環(huán)境里日志文件基本都做了輪轉切割直接找到對應時段的文件比在一個大文件里硬翻效率高得多。3.2 awk取列和統(tǒng)計結構化整理數(shù)據(jù)grep篩完行之后很多場景需要進一步提取特定列。awk就是干這個的。它按分隔符把每一行拆成字段默認按空格或制表符分割用$1、$2……引用對應列。接著上面的場景假設日志格式是“時間 IP 請求路徑 狀態(tài)碼”想找出所有返回5xx錯誤的請求路徑awk $4 ~ /^5[0-9][0-9]$/ {print $3, $4} app.log這條命令的意思是第四列以5開頭、后面跟兩位數(shù)字的把第三列和第四列打出來。這里$4是狀態(tài)碼$3是請求路徑。awk真正的威力在于它是一門小型編程語言支持變量、循環(huán)、條件判斷。比如統(tǒng)計每個IP的請求次數(shù)awk {count[$2]} END {for (ip in count) print ip, count[ip]} app.log | sort -k2 -nr | head這條命令是awk和sort、head的組合。count數(shù)組統(tǒng)計第二列每個IP的出現(xiàn)次數(shù)END塊在讀完所有行之后執(zhí)行把統(tǒng)計結果打印出來再交給sort按第二列數(shù)值從大到小排最后取前10條。這就是把“原始日志”變成“結論”的典型過程。注意awk里的數(shù)組下標如果列里包含重復值會被折疊統(tǒng)計所以這一步之前最好確認列內(nèi)容是否符合預期。我遇到過日志中IP列偶發(fā)為空的情況統(tǒng)計結果里多出一個空字符串的“IP”排查了半小時才發(fā)現(xiàn)是臟數(shù)據(jù)。3.3 sed精準替換修改配置不用開編輯器sed按行處理文本可以做替換、刪除、插入。最常用的替換場景是批量改配置。比如把配置文件里所有監(jiān)聽8080端口的配置改成9090sed -i s/8080/9090/g nginx.conf這個命令的讀法是-i表示直接修改文件s表示替換8080是查找模式9090是替換內(nèi)容g表示全局替換不只是在每行第一次出現(xiàn)時替換。有幾個坑要提醒-i參數(shù)在修改前最好先不加直接跑一遍看輸出對不對確認無誤再加-i真正寫回文件。如果配置文件里有多種8080含義比如注釋里也提到了8080建議先grep確認所有出現(xiàn)位置再決定替換范圍。sed的正則用的是基礎正則和grep的擴展正則、awk的正則都有細微差別同樣一個表達式在不同工具里可能含義不同。比如在基礎正則里是普通字符要加反斜杠轉義為\才表示“一個或多個”。3.4 sort、uniq做去重統(tǒng)計數(shù)據(jù)收口靠它倆sort給行排序uniq去除相鄰重復行。注意uniq只能去重相鄰的重復行所以必須先sort再uniq這倆幾乎總是連著用。日志去重統(tǒng)計的標準三連sort access.log | uniq -c | sort -rn | head -20先排序再去重并顯示每行重復次數(shù)-c再按次數(shù)從大到小排列-rn最后取前20條。這個組合在分析日志里“哪些錯誤反復出現(xiàn)”時非常高效。4. 進程管理的實操復盤4.1 ps和top靜態(tài)與動態(tài)結合看ps -ef和ps aux是日常查看進程最常用的兩條命令。它們的區(qū)別在于輸出格式不同前者偏向顯示父子關系和完整命令行后者偏向顯示CPU和內(nèi)存占用。排查CPU飆高的標準流程我一般這樣走top -b -n 1這個命令用批處理模式跑一次并退出避免動態(tài)刷新帶來的干擾。在腳本或排查記錄時比直接交互式top更好用。如果看到某個進程CPU占用率接近100%再深入一步看它的線程分布top -H -p PID-H參數(shù)按線程展示-p指定進程ID。這一步非常關鍵因為Java、Python這類多線程應用進程整體CPU高但具體是哪個線程在“燒”CPU必須切到線程級才看得清。我曾經(jīng)排查過一個服務偶發(fā)卡頓進程CPU看起來才60%但切到線程視圖后立刻看到一個線程占用打滿最后定位到是某個異步任務的死循環(huán)。4.2 kill與其他信號不是只有強殺kill默認發(fā)送TERM信號15請求進程正常退出。如果進程不響應才會用到KILL信號9強制終止。除這兩個之外常見信號還有信號數(shù)值作用HUP1掛斷常用于重讀配置文件INT2鍵盤中斷等價于CtrlCTERM15默認終止信號進程可自行清理KILL9強制終止不可捕獲不可忽略STOP19暫停進程不終止CONT18繼續(xù)已暫停的進程實際運維中改完nginx配置后讓配置立即生效不需要重啟進程只需要發(fā)送HUP信號kill -HUP [nginx的PID]這個操作的原理是nginx主進程收到HUP信號后會重新讀取配置文件并拉起新的worker進程比stop再start快而且不會中斷正在處理的連接。這個技巧比直接重啟優(yōu)雅得多也是老運維和新人之間一個很小的分水嶺。4.3 nice和renice讓進程按優(yōu)先級跑Linux的CPU調(diào)度是按優(yōu)先級搶占的優(yōu)先級數(shù)值范圍是-20到19數(shù)值越小優(yōu)先級越高。普通用戶只能調(diào)高nice值降低優(yōu)先級只有root能調(diào)低nice值提高優(yōu)先級。啟動一個新任務時指定優(yōu)先級nice -n 10 ./backup_script.sh對已經(jīng)運行的進程調(diào)整優(yōu)先級renice -n 10 -p PID一個典型場景是白天業(yè)務高峰期不要跑全量備份腳本但如果非要跑就把它nice調(diào)高一些讓它把CPU讓給業(yè)務進程。我當時的實操環(huán)境里跑過一次全量數(shù)據(jù)導出把進程nice設為10之后業(yè)務側高負載時的響應延遲明顯比默認優(yōu)先級的情況好。這個細節(jié)在高負載服務器上非常實用。5. 網(wǎng)絡排查與磁盤操作的踩坑實錄5.1 從ping到traceroute層層逼近問題點ping測通不代表網(wǎng)絡“沒問題”它只能說明ICMP協(xié)議在目標主機和源主機之間可達。很多服務器禁ping所以ping不通不一定服務不可用。判斷一個服務是否正常關鍵要看TCP端口是否連通。我習慣用ss命令替代老舊的netstat前者更快輸出也更清晰ss -ltn這條命令列出所有監(jiān)聽的TCP端口。-l是只看監(jiān)聽狀態(tài)-t是TCP協(xié)議-n是不解析域名直接顯示IP端口。如果能看到目標端口處于LISTEN狀態(tài)說明本機服務正常。如果本機端口正常但外部連接失敗大概率是防火墻或云安全組攔截了。路由追蹤用traceroutetraceroute -n 目標IP它逐跳打印從本機到目標IP經(jīng)過的路由節(jié)點。如果某一段出現(xiàn)星號或者延遲暴漲說明這一段網(wǎng)絡有擁塞或丟包。注意traceroute輸出里的每一跳代表一個路由器接口不代表一臺獨立機器。5.2 tcpdump抓包看真相網(wǎng)絡排查的最后一步往往要用tcpdump抓包確認數(shù)據(jù)包是否到達本機、是否發(fā)出響應。它需要root權限非常強大也容易產(chǎn)生大量輸出所以抓包必須指定過濾條件。最常見的抓包方式tcpdump -i eth0 port 8080 -c 100-i指定網(wǎng)卡port指定端口-c限定抓取100個包后自動停止。如果要保存抓包結果以便后續(xù)用圖形化工具分析加-w參數(shù)tcpdump -i eth0 port 8080 -w /tmp/capture.pcap抓完的pcap文件可以用Wireshark打開分析。注意tcpdump抓包時如果流量本身就很大不加過濾條件會直接打滿磁盤。我第一次實操時忘記加-c限制抓了十幾分鐘磁盤空間告急緊急用CtrlC終止才算沒把系統(tǒng)搞掛。養(yǎng)成“先加過濾條件、再加包數(shù)量限制”的習慣能避免很多麻煩。5.3 磁盤分區(qū)和掛載的完整流程虛擬機里新增了一塊磁盤系統(tǒng)里看不到第一步要確認系統(tǒng)是否識別到lsblklsblk列出所有塊設備包括磁盤、分區(qū)、掛載點和容量。如果新磁盤出現(xiàn)了但沒有任何分區(qū)接著用fdisk分區(qū)fdisk /dev/sdb進入fdisk交互界面后按n新建分區(qū)按p選主分區(qū)后續(xù)一路默認值即可最后按w寫入分區(qū)表。分區(qū)完成后分區(qū)表里會出現(xiàn)類似sdb1的條目。接下來格式化mkfs.ext4 /dev/sdb1創(chuàng)建ext4文件系統(tǒng)。其他常用格式還有xfsCentOS/RHEL默認、btrfs等按發(fā)行版習慣選擇。格式化之后才能掛載mkdir /data mount /dev/sdb1 /data掛載后還要讓開機自動掛載就得改/etc/fstab文件。手動掛載和開機掛載必須保持一致否則重啟后目錄是空的。修改fstab的關鍵一行/dev/sdb1 /data ext4 defaults 0 0寫完fstab后強烈建議先驗證一遍mount -a這條命令會重新讀取fstab并掛載其中所有條目。如果fstab寫錯了mount -a會直接報錯可以在重啟前及時修正。這個驗證步驟能避免一次服務器重啟后找不到文件系統(tǒng)的慘劇。注意云服務器里的數(shù)據(jù)盤某些場景建議用文件系統(tǒng)的UUID而不是/dev/sdX這種設備名來掛載。因為設備名在系統(tǒng)重啟后可能變化比如sdb變成sdc但UUID不會變。用blkid命令可以查到每個文件系統(tǒng)的UUIDfstab里寫UUID更穩(wěn)。5.4 我踩過的坑格式化前沒確認盤符新磁盤的分區(qū)、格式化、掛載這套流程本身不難真正危險的是在執(zhí)行命令時找錯了磁盤。我實操時遇到過一個很驚險的瞬間明明以為在操作/dev/sdc后來用lsblk復查才發(fā)現(xiàn)系統(tǒng)里還掛著一個數(shù)據(jù)盤/dev/sdb兩者塊大小和容量極其相似。從那以后我養(yǎng)成一個習慣任何磁盤操作前先跑lsblk和blkid把設備名、容量、已有分區(qū)、掛載點全部確認一遍再用df -h復查一遍現(xiàn)有磁盤狀態(tài)確保自己不會把已有數(shù)據(jù)的磁盤格式化掉。磁盤操作的容錯率極低多花兩分鐘確認對比可能的災難性損失非常劃算。6. 日志分析組合拳一個完整案例走查6.1 場景描述和原始日志為把前面的命令串起來我在本機搭了一個模擬場景。有一個訪問日志文件access.log內(nèi)容格式是“時間 客戶端IP 請求方法 路徑 狀態(tài)碼 耗時ms”我拿它做了完整分析。日志內(nèi)容大約幾百行其中混著正常請求和錯誤請求。先看文件整體情況wc -l access.log假設輸出是342行說明日志不大可以直接處理。如果日志有幾十萬行就要謹慎設計命令避免一次掃描太久。6.2 先整體后細節(jié)狀態(tài)碼分布第一步先看整體狀態(tài)碼分布awk {print $5} access.log | sort | uniq -c | sort -rn這里$5是狀態(tài)碼字段。輸出結果會像這樣280 200 42 404 12 500 8 502看到200占絕大多數(shù)但500和502加起來有20條說明服務確實存在不穩(wěn)定情況。這一步的價值在于不需要逐條看日志就能對系統(tǒng)整體健康狀況有個基本判斷。6.3 定位錯誤集中在哪些路徑上接下來精確定位哪些請求路徑返回5xx錯誤awk $5 500 {print $3, $5, $6} access.log | sort | uniq -c | sort -rn這條命令把狀態(tài)碼大于等于500的行拿出來打印請求方法、狀態(tài)碼、耗時然后統(tǒng)計排序。實際操作中大多錯誤路徑會集中在兩三個接口上這樣排查方向就很明確了。如果還懷疑錯誤是否隨時間集中出現(xiàn)可以加時間段分析awk $5 500 {print $1} access.log | cut -c12-19 | sort | uniq -c這里的$1是時間字段cut -c12-19截取出時分秒部分。通過統(tǒng)計各時間段的錯誤條數(shù)能看出錯誤是持續(xù)存在還是集中在某個時間窗口后者往往指向定時任務或流量高峰。6.4 綜合判斷加驗證分析完日志接著用ss確認相關服務端口狀態(tài)ss -ltn | grep 8080然后通過進程列表確認服務進程在跑ps aux | grep [服務名]這里多提一句grep加方括號的寫法grep [服]務名是為了避免grep進程本身匹配到自己。如果不加方括號ps輸出里的那一行grep命令也會被自己匹配到干擾判斷。這是很多教程不會特意提的小細節(jié)但實際排查時很實用。至此這輪日志排查就完成了一個閉環(huán)從原始日志到狀態(tài)碼分布從錯誤集中路徑到時間窗口再結合端口和進程狀態(tài)基本能確定問題方向。7. 高頻報錯和排查速查實操過程中一定會遇到報錯這里把我遇到過且典型的幾個列出來方便對照排查。7.1 “Permission denied”類文件或目錄權限不足。先用ls -l看權限位再用id確認當前用戶是否屬于目標文件的所有者或所屬組。ls -l /path/to/file id如果確認權限沒問題但還是拒絕訪問檢查SELinux是否攔截用getenforce查看狀態(tài)。SELinux開啟且策略不匹配時即使權限位完全正確服務也可能無法讀取文件。這種情況在CentOS系系統(tǒng)上尤其常見。7.2 “command not found”類命令不在PATH路徑里或者包未安裝。先which看命令是否存在再用包管理器安裝。which tcpdump無輸出說明沒裝CentOS系用yum install tcpdumpDebian系用apt install tcpdump。注意某些基礎命令在不同發(fā)行版里歸屬不同包比如ifconfig在較新系統(tǒng)中可能不存在需要改用ip命令。7.3 “Address already in use”類端口被占用。用ss -ltn找到占用端口的進程再決定是kill進程還是換端口。ss -ltnp | grep 8080-p參數(shù)會顯示對應進程PID和名稱。拿到PID后用ps確認是什么程序確認可以停止后kill掉。如果端口被系統(tǒng)隨機分配給某個內(nèi)核線程占用排查起來更麻煩但多數(shù)場景就是某個舊進程沒退干凈。7.4 系統(tǒng)命令超時或無響應這種情況多發(fā)生在負載過高時。先看load averageuptime三列數(shù)字分別代表1分鐘、5分鐘、15分鐘平均負載。如果15分鐘負載都比CPU核數(shù)高很多說明系統(tǒng)長時間處于高負載狀態(tài)。此時再配合top看具體是哪個進程吃資源確認后用kill或renice處理。報錯場景檢查命令處理思路權限拒絕ls -l、id、getenforce權限位、用戶歸屬、SELinux命令找不到which確認是否存在按發(fā)行版安裝端口被占用ss -ltnp確認進程停止或換端口系統(tǒng)無響應uptime、top看負載定位吃資源的進程8. 自定義腳本串起日常巡檢8.1 腳本思路和核心命令組合把日志分析、進程檢查、磁盤查詢整合成一個快速巡檢腳本是我覺得實戰(zhàn)價值最大的一步。這個腳本不復雜但能一次性輸出系統(tǒng)關鍵狀態(tài)。腳本思路分四塊系統(tǒng)負載、內(nèi)存余量、磁盤占用、監(jiān)聽端口。核心命令組合如下#!/bin/bash echo 系統(tǒng)負載 uptime echo 內(nèi)存 free -h echo 磁盤 df -h echo 監(jiān)聽端口 ss -ltn這里每條命令的輸出都經(jīng)過格式化方便快速閱讀。腳本可以保存在/usr/local/bin/下并加執(zhí)行權限后續(xù)直接調(diào)用名字就能跑。注意腳本里的命令路徑建議用絕對路徑或者確保PATH環(huán)境變量在非交互式Shell下包含了這些命令路徑。cron執(zhí)行腳本時PATH環(huán)境變量往往比交互式Shell精簡很多直接寫命令名有時會找不到。用which uptime查到的絕對路徑寫進腳本更穩(wěn)。8.2 保存日志和告警日常巡檢光打印到屏幕不夠還要留痕??梢园演敵鲋囟ㄏ虻饺罩疚募⒓訒r間戳echo $(date %Y-%m-%d %H:%M:%S) /var/log/syscheck.log uptime /var/log/syscheck.log free -h /var/log/syscheck.log如果希望異常時提醒可以對關鍵指標做判斷。比如磁盤使用率超過90%時輸出成警告disk_usage$(df / | awk NR2 {print $5} | sed s/%//) if [ $disk_usage -gt 90 ]; then echo 磁盤使用率過高: $disk_usage% /var/log/syscheck.log fi這里的邏輯是df /取根分區(qū)使用率awk取第五列的百分比sed把百分號去掉然后再和90做數(shù)值比較。這個腳本可以放到crontab里定時執(zhí)行實現(xiàn)每天固定時間的自動巡檢。8.3 定時任務注意事項配置croncrontab -e添加一行0 2 * * * /usr/local/bin/syscheck.sh這樣每天凌晨2點執(zhí)行一次巡檢。放在凌晨是為了避開業(yè)務高峰期避免腳本本身的系統(tǒng)資源占用影響業(yè)務。我的體會是這類巡檢腳本不需要很復雜關鍵是能把高頻檢查項固化下來。真遇到問題的時候先跑一遍巡檢腳本拿到整體狀態(tài)再針對異常項深入排查效率遠比一條條敲命令高得多。9. 一些值得長期堅持的習慣實操多了以后我發(fā)現(xiàn)真正拉開效率差距的不是某個神級技巧而是一系列小習慣。第一命令先想清楚再執(zhí)行尤其是刪除、格式化、覆蓋這類不可逆操作。Linux命令一旦執(zhí)行沒有“撤銷”按鍵。我會在關鍵命令前先跑一遍dry run或先echo打印命令本身確認無誤再真正執(zhí)行。第二每學到一條新命令隨手記下適用場景和注意事項而不是只記命令拼寫。命令拼寫可以查手冊使用場景和踩過的坑往往查不到。我自己維護了一個Markdown筆記按“文本處理”“進程管理”“網(wǎng)絡排查”分類遇到問題先翻筆記已經(jīng)解決過的問題不再需要重新排查一遍。第三保持“驗證”的習慣。任何修改配置的操作執(zhí)行后都要用查看類命令確認生效。改完fstab跑mount -a改完nginx配置kill -HUP后再用curl驗證響應改完防火墻規(guī)則后用ss或telnet驗證端口仍然正常。驗證這一步看似多余實際上能擋住大部分低級錯誤。第四日志和輸出要留痕。日常排查的現(xiàn)場輸出如果數(shù)據(jù)量大不要只靠肉眼翻養(yǎng)成輸出到文件再分析的習慣。很多問題需要對比前后變化留有原始輸出就是留下了對比的基準線。第五模板化。像巡檢腳本這種重復性工作一定要模板化、腳本化。人總會疲勞腳本不會。把判斷邏輯寫進腳本既統(tǒng)一了檢查口徑也避免了臨場手忙腳亂。