戰(zhàn):從管道組合到服務(wù)器故障排查指南)
1. 先別急著背命令清單把命令當(dāng)成跟系統(tǒng)對話早些年我剛接觸 Linux 命令的時候干過一件現(xiàn)在想起來有點(diǎn)好笑的事找了一份《常用 Linux 命令大全》把 ls、cd、cp、mv 的參數(shù)背得滾瓜爛熟結(jié)果到了真正需要排查問題的時候依然兩眼一摸黑。后來真正讓我對 Linux 命令開竅的不是某本速查手冊而是一次在服務(wù)器上排查故障時的經(jīng)歷——我把一條一條看起來平平無奇的命令用管道串了起來突然意識到原來這些命令并不是一份需要死記硬背的清單它們本質(zhì)上是一種向操作系統(tǒng)提問的方式。這篇文章不打算給你羅列幾百條命令的用法我更想聊的是怎么把命令用起來怎么從一條單命令出發(fā)逐步組合成能解決實(shí)際問題的信息流水線排查服務(wù)器問題時應(yīng)該按什么思路選擇命令以及那些文檔里通常不會寫、但實(shí)戰(zhàn)里特別關(guān)鍵的細(xì)節(jié)。適合剛學(xué) Linux、總感覺命令學(xué)了就忘的新手也適合已經(jīng)在日常使用 Linux、但遇到問題仍然不知道從何下手的進(jìn)階用戶。1.1 命令是提問不是背誦清單我后來總結(jié)出一個觀點(diǎn)每一條命令都在回答一個具體的問題。ls 回答這個目錄里有什么ps 回答現(xiàn)在系統(tǒng)里有哪些進(jìn)程在跑df 回答磁盤空間還剩多少。當(dāng)你把命令理解成提問工具而不是要背的單詞學(xué)習(xí)方式自然就變了——遇到陌生命令第一反應(yīng)不再是我又要背一個了而是這條命令能幫我回答什么疑問。順著這個思路命令后面的選項(xiàng)和參數(shù)也不過是讓答案更精確的限定條件。比如 ps 這條命令ps aux 和 ps -ef 都能查看進(jìn)程呢但輸出格式不同適合的場景也不同。你不需要把幾十個選項(xiàng)全部背下來只需要知道這條命令能回答進(jìn)程狀態(tài)這一類問題然后遇到實(shí)際需求時去查它的用法。查用法有兩條路man 命令名或者 命令名 --help。很多人看到 man 手冊那么長就退縮其實(shí)根本不需要從頭讀到尾只看你關(guān)心的那個選項(xiàng)就行。真正重要的不是把手冊讀完而是養(yǎng)成先查后試的習(xí)慣。這個習(xí)慣比任何命令大全都管用因?yàn)橄到y(tǒng)自帶的幫助信息永遠(yuǎn)比別人的筆記更新、更貼合手頭這個版本。1.2 從最小可運(yùn)行命令開始別一上來就堆參數(shù)我見過不少人一上來就寫特別長的命令比如 find 配合 -exec、多層管道、一堆選項(xiàng)全部疊加一旦報(bào)錯根本不知道是哪一個環(huán)節(jié)出了問題。我的習(xí)慣剛好相反先跑一個最小版本確認(rèn)命令本身能正常工作輸出格式也符合預(yù)期然后再一點(diǎn)點(diǎn)把過濾條件、排序、統(tǒng)計(jì)加上去。這個過程很像排查電路故障先確認(rèn)總閘有電再逐條支路檢查而不是一上來就把所有開關(guān)都按一遍。舉個例子你想用 awk 從日志里取某一列如果上來就寫 awk {print $2}結(jié)果發(fā)現(xiàn) $2 根本不是你想要的那一列因?yàn)槟銐焊鶝]見過日志原始長什么樣。正確做法是先 head -n 5 日志文件看一眼列是怎么排的確認(rèn)第幾列是IP、第幾列是時間再寫 awk。這個先看輸出、再動手處理的習(xí)慣能幫你省掉大量自我懷疑的時間。配套的技巧叫小范圍驗(yàn)證處理大文件時先用 head 或 grep head 把輸入縮小邏輯跑通之后再對全量數(shù)據(jù)執(zhí)行。尤其是 sed、awk 這類會修改內(nèi)容的命令強(qiáng)烈建議先在測試目錄或小樣本上試一遍確認(rèn)結(jié)果符合預(yù)期再正式執(zhí)行。別嫌這一步啰嗦真出問題的時候它會讓你少說很多次完蛋了。這套方法同樣適用于后面要講的管道命令——每次只加一段跑一下確認(rèn)沒問題再繼續(xù)拼。2. 一條排查命令是怎么長出來的管道組合實(shí)戰(zhàn)很多人學(xué)命令是一條一條學(xué)的但實(shí)際干活的時候真正體現(xiàn)功力的地方是把命令用管道串起來。管道說白了就是把前一條命令的輸出交給后一條命令作為輸入。用好了一條命令就能完成一次小規(guī)模的數(shù)據(jù)分析。我拿一個特別常見的場景來講某天服務(wù)響應(yīng)變慢懷疑有客戶端在反復(fù)刷某個接口日志目錄里放著訪問日志現(xiàn)在想找出到底哪些 IP 在頻繁請求這個接口。2.1 場景與需求我要從日志里找到誰在刷接口先別急著寫命令第一步是看一眼日志長什么樣。執(zhí)行 tail -n 20 訪問日志路徑確認(rèn)列格式。這一步是整條排查命令的地基因?yàn)楹竺嫒∧囊涣?、怎么過濾完全取決于日志里字段的排列方式。假設(shè)我們看到日志格式大致是IP 時間 請求方法 請求地址 狀態(tài)碼那 IP 就在第一列。很多人忽略這個步驟直接 grep 然后 awk {print $1}結(jié)果日志格式稍有變化取到的列根本不是自己想要的東西。這就是沒看清現(xiàn)場就動手的典型失誤。日志格式確認(rèn)之后你的需求才能轉(zhuǎn)成清晰的命令目標(biāo)先過濾出包含指定接口的日志行再從這些行里提取 IP 字段最后按 IP 去重并統(tǒng)計(jì)請求次數(shù)。每一步對應(yīng)什么命令這時就非常自然了。2.2 逐段拼接每加一步都驗(yàn)證一遍我按實(shí)際排查過程把這條命令拆開你可以看到它是怎么一步步長出來的。第一步只篩選出相關(guān)請求grep api/login 訪問日志路徑跑完先看輸出是否符合預(yù)期如果行數(shù)太多可以先在末尾加 head -n 10 看幾條樣例。第二步把 IP 字段取出來grep api/login 訪問日志路徑 | awk {print $1}這時輸出會是一堆可能重復(fù)的 IP。第三步排序并統(tǒng)計(jì)次數(shù)。這里有一個很關(guān)鍵的順序問題必須先 sort 再 uniq -c。因?yàn)?uniq 默認(rèn)只統(tǒng)計(jì)相鄰的重復(fù)行如果同一個 IP 在文件中是分段出現(xiàn)的直接 uniq -c 會把一個 IP 統(tǒng)計(jì)成好幾段結(jié)果完全錯誤。正確寫法是grep api/login 訪問日志路徑 | awk {print $1} | sort | uniq -c到這一步輸出變成次數(shù) IP的形式。第四步按次數(shù)降序排列并只保留前 20 個結(jié)果grep api/login 訪問日志路徑 | awk {print $1} | sort | uniq -c | sort -rn | head -n 20看到這里你應(yīng)該明白了這條命令不是背出來的而是從一個疑問出發(fā)通過不斷驗(yàn)證中間輸出自然組合出來的。每加一個管道段我都會先跑一遍看一眼輸出內(nèi)容是不是我想要的再決定下一步往哪邊走。這種逐段驗(yàn)證的拼法比一口氣寫完長命令要可靠得多。2.3 組合管道時容易翻車的幾個細(xì)節(jié)管道好用但有幾個坑必須提醒。第一個坑是管道左側(cè)失敗右側(cè)照跑。比如文件不存在時 grep 會報(bào)錯但整個管道的退出狀態(tài)取決于最后一個命令。如果你在腳本里啟用了 set -e可能就不會因?yàn)槲募淮嬖诙袛嗄_本問題會被靜默放過去后面拿到一堆錯誤數(shù)據(jù)時反而更難排查。第二個坑是隱藏字符。有些日志文件里帶著 \r 回車符或者亂碼輸出看起來一切正常但 sort 和 uniq 的結(jié)果就是不符合預(yù)期。遇到可疑情況可以用 cat -A 文件名 | head 看一眼文件中是否藏著看不見的控制字符再決定要不要用 tr 或 sed 先清理。第三個坑是 awk 列號寫死的問題。如果日志里大部分行有 7 列但偶爾幾行因?yàn)楦袷疆惓V挥?5 列取 $1 可能還算穩(wěn)定取 $4 就可能錯位。處理這類臟數(shù)據(jù)先分幾行看一看字段結(jié)構(gòu)差異再選擇取列方式。我的建議是拼管道命令時每加一段就跑一遍確認(rèn)中間結(jié)果正常再繼續(xù)往后面接。這個習(xí)慣幫我在排錯時節(jié)省了大量時間比任何命令速查表都實(shí)在。3. 資源狀態(tài)排查進(jìn)程、內(nèi)存、磁盤的真實(shí)場景命令只有放到真實(shí)場景里反復(fù)用才會真正變成自己的東西。服務(wù)器出問題的時候其實(shí)是學(xué)習(xí)命令最好的機(jī)會。這一節(jié)我挑三個高頻場景講一下我是怎么看狀態(tài)、怎么快速把問題定位到具體方向的。3.1 進(jìn)程ps aux 只是起點(diǎn)/proc 里才是真正的細(xì)節(jié)ps aux 大家都會用但實(shí)際排查時有幾個細(xì)節(jié)很容易被忽略。首先ps aux 默認(rèn)按 PID 排序如果想找 CPU 或內(nèi)存占用最高的進(jìn)程要么用 sort 輔助要么進(jìn) top 再按對應(yīng)列排序。其次ps aux 能看到進(jìn)程的基本狀態(tài)但看不到這個進(jìn)程的完整啟動命令、當(dāng)前工作目錄、環(huán)境變量以及它打開了哪些文件。這些細(xì)節(jié)要去 /proc/PID 目錄里挖。比如某個進(jìn)程 CPU 占用很高你想知道它到底在干什么可以先看 /proc/PID/cmdline 拿到完整的啟動參數(shù)再看 /proc/PID/status 里的線程數(shù)和狀態(tài)信息。如果懷疑進(jìn)程打開了某個文件不釋放可以用 lsof -p PID 查看它持有的文件句柄。說實(shí)話剛接觸 Linux 的人會覺得 /proc 下一堆數(shù)字目錄很怪但用熟了以后會發(fā)現(xiàn)它幾乎是系統(tǒng)主動敞開的一扇觀察窗口。補(bǔ)充一個實(shí)用命令想按內(nèi)存占用排序找進(jìn)程可以直接寫 ps aux --sort-%mem | head -n 10一步到位。不過要提醒一點(diǎn)進(jìn)程的 RSS 內(nèi)存包含它加載的共享庫占用的那部分把所有進(jìn)程的 RSS 簡單相加來估算系統(tǒng)總內(nèi)存需求是不準(zhǔn)確的這一點(diǎn)初學(xué)者非常容易誤解。3.2 磁盤df 滿了du 卻找不到大文件磁盤滿了但不知道是誰占的這個場景幾乎每個運(yùn)維和開發(fā)者都遇到過。df 和 du 的視角不一樣df 看的是文件系統(tǒng)整體用了多少du 看的是某個目錄下所有文件實(shí)際占用多少。如果 df -h 顯示根分區(qū)已經(jīng) 100%但到根目錄執(zhí)行 du -sh * 逐項(xiàng)相加后發(fā)現(xiàn)遠(yuǎn)小于總量說明一定有什么東西在看不見地占著空間。最常見的元兇有兩個。第一個是已被刪除但還被進(jìn)程占用的文件進(jìn)程打開了一個文件隨后文件被刪除但進(jìn)程沒有關(guān)閉句柄磁盤空間就不會釋放。df 能看到空間沒了du 卻無論如何也找不到這個大文件。這種情況用 lsof | grep deleted 就能把它揪出來。第二個是 inode 耗盡小文件太多把索引節(jié)點(diǎn)用完了df 顯示空間還有剩余但新文件就是創(chuàng)建不出來。這時候要執(zhí)行 df -i 看 inode 使用率。很多人只盯 df -h不看 df -i所以遇到空間夠但寫不進(jìn)文件這種詭異問題就會卡住。還有一種情況是目錄被重復(fù)掛載。一個目錄被掛到兩個位置du 默認(rèn)會跨掛載點(diǎn)重復(fù)計(jì)算導(dǎo)致統(tǒng)計(jì)結(jié)果虛高。如果只想看當(dāng)前文件系統(tǒng)自己的用量給 du 加上 -x 參數(shù)讓它不跨越文件系統(tǒng)邊界。以后再遇到df 和 du 對不上時別急著懷疑命令先按這三條逐個排查思路會清楚很多。3.3 內(nèi)存free 里的 buffer/cache 不是占用執(zhí)行 free -h 的時候很多新手看到 used 很高、buff/cache 也很大就開始慌了覺得內(nèi)存是不是快不夠了。實(shí)際上buff/cache 是 Linux 的一種正常內(nèi)存管理機(jī)制把暫時用不上的空閑內(nèi)存拿去做文件緩存等應(yīng)用程序需要更多內(nèi)存時這些緩存會被隨時釋放回來。真正判斷內(nèi)存夠不夠要看的是 available 這一列它表示在不發(fā)生 swap 的情況下還能分配給新進(jìn)程多少內(nèi)存。判斷內(nèi)存壓力的信號有這幾個swap 使用率持續(xù)上漲、系統(tǒng)日志里出現(xiàn) OOM 相關(guān)的記錄、top 里某些進(jìn)程被莫名其妙殺掉。遇到這些情況再去查到底是哪個進(jìn)程占得多比直接升級內(nèi)存更有效。我之前處理過類似場景一個服務(wù)平時內(nèi)存占用正常但每到某個固定時間點(diǎn)就掛一次后來翻日志發(fā)現(xiàn)是定時任務(wù)和主服務(wù)同時跑內(nèi)存峰值超標(biāo)了。整個過程用到的命令也就是 free、top、journalctl 這些但核心在于是否愿意順著現(xiàn)象多問幾層為什么而不是停留在重啟一下試試。4. 少跑冤枉路的排查思路從現(xiàn)象到根因命令只是工具思路決定你花多長時間解決問題。不少人在排查時喜歡病急亂投醫(yī)這條命令不行換那條最后直接重啟大法收場。其實(shí)只要按層次逐步排除很多問題都能在幾分鐘內(nèi)鎖定到很小的范圍。這一節(jié)我想分享的是我在實(shí)際排錯中沉淀下來的分層思考框架。4.1 先確認(rèn)現(xiàn)象在哪一層再決定用什么命令一個服務(wù)訪問不了可能性實(shí)際上非常多客戶端 DNS 解析失敗、網(wǎng)絡(luò)不通、服務(wù)端口沒監(jiān)聽、服務(wù)進(jìn)程掛了、防火墻規(guī)則攔截、后端數(shù)據(jù)庫連不上、應(yīng)用代碼本身報(bào)錯。如果一上來就 ping 網(wǎng)關(guān)很可能把時間浪費(fèi)在錯誤的方向上。我的習(xí)慣是把問題分四層看應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、系統(tǒng)層按順序逐層驗(yàn)證。第一層先在服務(wù)器本機(jī)測應(yīng)用層用 curl 訪問本機(jī)地址如果服務(wù)本身和端口都正常curl 應(yīng)該很快返回業(yè)務(wù)響應(yīng)。第二層從內(nèi)網(wǎng)或外部機(jī)器訪問看是不是網(wǎng)絡(luò)路徑或防火墻攔截的問題。第三層查服務(wù)日志確認(rèn)是業(yè)務(wù)邏輯報(bào)錯還是資源不足。每一層都用一兩個命令去驗(yàn)證然后縮小范圍。比如 curl 本機(jī)通、外部不通問題大概率在網(wǎng)絡(luò)層或防火墻本機(jī) curl 都不通那就直接往進(jìn)程和端口方向查。這套思路聽著簡單但實(shí)際很多人遇到問題的第一個動作就是重啟服務(wù)。重啟確實(shí)能讓問題暫時消失但也會把現(xiàn)場破壞掉——進(jìn)程狀態(tài)、網(wǎng)絡(luò)連接、日志上下文全部重置之后再想復(fù)盤根因就非常被動了。我的原則是重啟之前至少先保存日志、記錄進(jìn)程狀態(tài)、記下時間線這三樣?xùn)|西。保住現(xiàn)場比急著恢復(fù)服務(wù)更有利于找到真因。4.2 網(wǎng)絡(luò)類命令的高頻組合與正確用法網(wǎng)絡(luò)排查的命令本身不難難的是理解每一條命令到底能證明什么。ping 通了只能說明 ICMP 這一層通不能證明業(yè)務(wù)端口是通的端口能連上說明 TCP 握手成功但也不代表應(yīng)用層正常。所以我常用的組合是先 ping 看基礎(chǔ)連通性再 ss -tlnp 看本機(jī)端口是否在監(jiān)聽然后用 nc 從另一端測一下端口連通性最后用 curl -v 帶超時參數(shù)去測應(yīng)用層響應(yīng)。每一條命令回答的層都不同組合起來才能完成定位。舉一個實(shí)際的排查過程某次遇到網(wǎng)站間歇性打不開我在服務(wù)器本機(jī)用 curl 訪問一切正常但從外部訪問就超時。接下來用 nc -vz 目標(biāo)IP 端口 測端口發(fā)現(xiàn) TCP 層也通不過于是基本判斷問題出在網(wǎng)絡(luò)路徑或防火墻。再檢查防火墻規(guī)則和安全組配置很快就找到了原因。全程沒有用任何復(fù)雜的命令但每一條都完成了排除一個方向的任務(wù)。這里有個容易被忽略的細(xì)節(jié)nc、mtr、dig 這類命令在部分精簡安裝的 Linux 上默認(rèn)不存在。在網(wǎng)絡(luò)問題排查之前先確認(rèn)系統(tǒng)里有沒有這些工具缺什么就裝什么否則查了半天才發(fā)現(xiàn)命令根本不存在節(jié)奏就被完全打亂了。另外curl 的 -w 參數(shù)可以輸出連接耗時、總時間等指標(biāo)用來判斷慢在哪一段尤其好用值得專門花兩分鐘熟悉一下。4.3 日志時間線別只盯著最新幾行日志是排查問題最直接的現(xiàn)場記錄但很多人只會 tail -n 100 看最近幾行。問題如果發(fā)生在幾小時前等你發(fā)現(xiàn)并登錄服務(wù)器的時候關(guān)鍵日志可能早就被新內(nèi)容沖掉了。正確的做法是先確定問題是從什么時候開始出現(xiàn)的然后把那個時間窗口附近的日志完整拉出來看。目前我用的比較多的方式是 journalctl 這套執(zhí)行 journalctl -u 服務(wù)名 --since 2 hours ago 可以看某個服務(wù)最近兩個小時的日志還能用 --until 進(jìn)一步收窄時間窗口。接著用 grep 按關(guān)鍵詞過濾比如搜 OOM、error、timeout然后再順著時間線把上下文完整看一遍。很多時候真正的根因藏在錯誤日志前面幾十行里只看孤零零的一句報(bào)錯很容易被誤導(dǎo)到錯誤的方向。如果系統(tǒng)沒有啟用 journalctl日志只寫在傳統(tǒng)文件里可以先看日志文件的修改時間來判斷問題的大致時間點(diǎn)再從那個時間點(diǎn)附近取日志。無論用哪種方式核心方法是一致的把錯誤發(fā)生時刻前后幾分鐘的信息放到一起看。排查問題要看時間線而不是只看單個報(bào)錯點(diǎn)這是我跟很多人反復(fù)強(qiáng)調(diào)的一點(diǎn)。5. 被默認(rèn)忽略的命令習(xí)慣安全與效率兼得最后想聊的是命令使用習(xí)慣。這部分很少有人專門教但踩過的坑往往最疼。我總結(jié)了幾條可以直接照做的經(jīng)驗(yàn)?zāi)軒湍闵僮吆芏鄰澛贰?.1 rm 這類危險操作給自己上個保險rm -rf 是很多人心中的噩夢。最常見的風(fēng)險來源是這幾個路徑變量為空、路徑拼寫錯誤、在錯誤的目錄下執(zhí)行。我的建議有三條。第一把 rm 替換成帶回收站功能的方式比如設(shè)置 alias rmtrash-put或者寫一個自定義函數(shù)把刪除的文件移動到一個專門的回收目錄里這樣至少還有后悔藥可以吃。第二如果必須在腳本里用 rm先判斷變量是否為非空比如 [[ -n $目錄變量 ]] 確認(rèn)后再繼續(xù)操作。第三執(zhí)行刪除之前先 pwd 確認(rèn)當(dāng)前目錄再 ls 確認(rèn)目標(biāo)路徑。有人覺得這些習(xí)慣太啰嗦但真出過一次事就會明白多花十秒鐘確認(rèn)比花一整晚恢復(fù)數(shù)據(jù)劃算太多。尤其是在生產(chǎn)環(huán)境里rm 的安全習(xí)慣應(yīng)該變成肌肉記憶不靠運(yùn)氣靠流程。5.2 history、alias、配置把常用命令沉淀成自己的裝備命令用好之后很多人還是每次重復(fù)敲一長串效率很低。我習(xí)慣把高頻組合寫成別名比如 alias llls -lh、alias ggrep、alias ..cd ..寫進(jìn) ~/.bashrc 或 ~/.zshrc 之后日常操作會舒服很多。但這里有一個經(jīng)典坑要提醒在腳本里不要依賴別名。非交互式 shell 默認(rèn)不會展開 alias你明明配置了 alias ggrep在腳本里寫 g abc file 卻可能報(bào)命令找不到這個問題會讓不少人困惑很久。歷史記錄也值得好好配置。默認(rèn)情況下 history 只記錄命令本身不記錄時間長度也有限。我通常會在配置里加這幾行HISTTIMEFORMAT%F %T HISTSIZE10000 HISTFILESIZE20000加上之后history 輸出會帶上時間戳復(fù)盤問題的時候會非常有用。還有一條安全習(xí)慣必須強(qiáng)調(diào)不要把密碼、密鑰、token 直接寫在命令行里因?yàn)?history 會記錄腳本里也會留痕。如果確實(shí)需要應(yīng)該通過環(huán)境變量或配置文件讀取不要圖省事直接明文寫在命令里。5.3 重定向、通配符、sudo 的常見坑重定向是新手最容易出問題的地方。第一點(diǎn)是 會覆蓋文件 會追加文件第二點(diǎn)是 21 表示把標(biāo)準(zhǔn)錯誤重定向到標(biāo)準(zhǔn)輸出當(dāng)前指向的位置這兩者順序不同結(jié)果也完全不同。一個非常經(jīng)典的錯誤是執(zhí)行 sudo echo 1 /某個root屬主的文件結(jié)果報(bào)權(quán)限不足因?yàn)橹囟ㄏ蚴钱?dāng)前 shell 打開的sudo 只作用于 echo 命令本身。正確做法是 echo 1 | sudo tee /某個root屬主的文件或者 sudo bash -c echo 1 /某個root屬主的文件。通配符也有一個容易踩的坑。rm.log 在沒有匹配文件時.log 這個字面字符串會原樣傳給 rm然后 rm 報(bào)錯文件不存在。更危險的情況是如果目錄里恰好有一個文件叫 *.log這個命令會把它也刪掉。要避免這類意外可以寫 rm -- *.log雙橫線表示后面的參數(shù)都作為文件名處理。通配符本質(zhì)上是 shell 先做展開再交給命令執(zhí)行理解了這個機(jī)制你才能控制它而不是被它坑到。最后說一句 sudo 的使用邊界。很多人習(xí)慣遇到權(quán)限問題就一長串 sudo但這會掩蓋真實(shí)的權(quán)限問題。能用普通用戶執(zhí)行就不要用 root 身份能限制在單條命令上就不要開一個 root shell。這句話聽起來像老生常談但生產(chǎn)環(huán)境里權(quán)限最小化是真的能兜底的。根據(jù)自己的經(jīng)驗(yàn)我最后分享一個小習(xí)慣每周挑一條平時用得少但知道很有用的命令比如 find、xargs、jq花十分鐘讀一遍它的手冊在一個測試目錄里用真實(shí)數(shù)據(jù)玩一遍然后思考它還能怎么跟別的命令組合。堅(jiān)持一個月你會發(fā)現(xiàn)自己能寫出來的命令結(jié)構(gòu)越來越豐富。Linux 命令這東西背了不用等于沒學(xué)用了并且認(rèn)真思考過才真正變成你自己的。