戰(zhàn)指南)
如果你問我開發(fā)、運(yùn)維、數(shù)據(jù)處理這些工作里最值得花時(shí)間練的基本功是什么我的答案會(huì)是文件操作命令。所謂“文件的應(yīng)用命令”就是把查看、查找、復(fù)制、移動(dòng)、改名、壓縮、統(tǒng)計(jì)這些動(dòng)作用終端里的一行命令去完成。你可能會(huì)說平時(shí)用圖形界面雙擊不就行了我起初也是這么想的直到我遇到幾個(gè)圖形界面完全搞不定的場景。這篇文章就把我實(shí)際在用的命令、參數(shù)、踩過的坑整理出來適合剛接觸終端的新手也適合希望把日常文件操作提速的開發(fā)者。1. 為什么文件操作一定要學(xué)會(huì)命令行1.1 圖形界面搞不定的場景我先講一個(gè)真實(shí)的工作場景。有一次我在處理一批日志文件大概有兩千多個(gè)按日期散落在幾十個(gè)目錄里。我需要把所有2024-06-*.log匯總到一個(gè)目錄再按小時(shí)統(tǒng)計(jì)每個(gè)時(shí)間段的請求量。如果靠文件管理器一個(gè)一個(gè)選先別說容易漏光是把窗口拖來拖去就得耗掉一下午。而用命令行一條find加一條grep幾秒鐘就出結(jié)果。還有一類場景是服務(wù)器維護(hù)。很多生產(chǎn)環(huán)境根本沒有圖形界面你只能通過終端登錄。這時(shí)候所有文件操作都必須用命令完成。你不可能對(duì)著遠(yuǎn)程服務(wù)器說“幫我把這個(gè)文件夾拖過去”只能靠cp、mv、tar這些命令。哪怕你平時(shí)只在本地用電腦總有一天你會(huì)需要登錄一臺(tái)云主機(jī)或者一個(gè)開發(fā)容器到時(shí)候再學(xué)就晚了。另外數(shù)據(jù)處理的場景更明顯。比如你有一份幾百M(fèi)B的CSV想看看里面有多少行、有哪些重復(fù)值、某個(gè)字段的分布情況。用Excel打開都可能卡半天但wc -l、sort、uniq、awk幾行命令就解決問題。這種場景下命令行不是“可選的技巧”而是真正能救命的能力。1.2 命令行真正的價(jià)值把操作變成文本圖形界面的操作本質(zhì)上是“點(diǎn)鼠標(biāo)”每一步都是獨(dú)立的、難以記錄的。而命令行的操作本質(zhì)上是“寫文本”每一個(gè)動(dòng)作都是一段字符串可以被復(fù)制、粘貼、修改、保存、重復(fù)執(zhí)行。這帶來一個(gè)非常重要的特性可重復(fù)性。你用圖形界面把一個(gè)目錄下的文件整理好下次遇到同樣的需求還得重新來一遍。但如果你把命令寫成一行或者一個(gè)腳本下次直接運(yùn)行就好結(jié)果完全一致。這就像做菜有菜譜而不是每次都靠手感。另一個(gè)特性是組合能力。命令行里每個(gè)命令只做一件事但你可以用管道|把它們串起來形成強(qiáng)大的流水線。比如find . -name *.tmp | xargs rm意思是“找到所有.tmp文件然后逐個(gè)刪除”。這種組合能力是圖形界面很難給你的。哪怕你用再高級(jí)的文件管理器也很難實(shí)現(xiàn)這種“查找 處理 匯總”的連鎖操作。所以學(xué)命令行不是裝“極客”而是把操作從“手工勞動(dòng)”升級(jí)成“可編程勞動(dòng)”。它不排斥圖形界面而是補(bǔ)充了圖形界面缺失的部分。我個(gè)人的習(xí)慣是簡單的一次性操作用圖形界面重復(fù)的、批量的、需要精確處理的操作用命令行。兩者配合效率才會(huì)最大化。2. 高頻必備文件操作命令全家桶這一部分我把日常使用頻率最高的命令梳理一遍。不需要一次全記住建議先記前兩三個(gè)然后邊用邊查。下面先給一個(gè)速查表后面再逐個(gè)展開。操作類型常用命令典型參數(shù)典型場景查看目錄內(nèi)容ls-lh、-a、-t看文件大小、隱藏文件查看文件類型file無識(shí)別不確定擴(kuò)展名的文件查看文件詳情stat無看時(shí)間戳、權(quán)限、inode查看文件內(nèi)容cat、less、head、tail-n、-f預(yù)覽、跟蹤日志復(fù)制cp-r、-a、-n單文件、整個(gè)目錄移動(dòng)/改名mv-i、-n移動(dòng)文件、重命名刪除rm-r、-f、-i刪文件、刪目錄查找find、locate-name、-size、-mtime按名字、大小、時(shí)間找文件壓縮解壓tar、zipczvf、xzvf、-r打包目錄、壓縮傳輸統(tǒng)計(jì)處理wc、grep、sort、awk-l、-c、-n、-k行數(shù)、過濾、分組統(tǒng)計(jì)2.1 查看文件的基本姿勢很多新手以為查看文件就是雙擊打開但在命令行里“查看”這個(gè)動(dòng)作有很多層次。首先是看目錄里有什么。ls -lh是我用得最多的命令-l顯示詳細(xì)信息-h把大小換成人類易讀的格式比如4.2M。如果你想看隱藏文件要加-a想按修改時(shí)間排序加-t想按文件大小排序加-S。我建議你直接給自己設(shè)置一個(gè)別名比如把ls默認(rèn)加上-lh省得每次都敲。然后是確認(rèn)文件到底是什么。這一步很多新手會(huì)忽略。文件名后綴不一定靠譜比如從網(wǎng)上下載的文件可能叫abc.txt但實(shí)際是個(gè)壓縮包。用file abc.txt就能看真實(shí)的文件類型它會(huì)讀取文件頭部特征來判斷而不是看擴(kuò)展名。這在處理未知來源文件時(shí)特別有用。如果你想看更詳細(xì)的元數(shù)據(jù)用stat。它會(huì)輸出文件的修改時(shí)間、訪問時(shí)間、大小、權(quán)限、inode 編號(hào)等信息。有一類很常見的故障是“文件明明改過了但程序讀到的還是舊內(nèi)容”這種時(shí)候stat能幫你確認(rèn)文件時(shí)間戳是否真的更新了。至于看內(nèi)容我的習(xí)慣是分情況選擇文件很小、想快速看全文用cat文件很大用less翻頁查看按q退出只想看開頭或結(jié)尾用head -n 10、tail -n 10一直盯著日志文件看新增內(nèi)容用tail -f。特別是tail -f排查線上問題的時(shí)候幾乎是標(biāo)配日志一有新行就立刻顯示相當(dāng)于給程序開了個(gè)實(shí)時(shí)監(jiān)控窗口。2.2 復(fù)制、移動(dòng)、刪除的細(xì)節(jié)這三個(gè)命令看著簡單但細(xì)節(jié)特別多很多事故都是在這上面發(fā)生的。復(fù)制命令cp最常見的問題是“目錄復(fù)制”和“權(quán)限保留”。如果你復(fù)制一個(gè)目錄不加-r系統(tǒng)會(huì)直接報(bào)錯(cuò)cp: -r not specified; omitting directory。正確寫法是cp -r dir1/ dir2/。如果目錄里的文件有特殊權(quán)限屬性建議改用cp -a它會(huì)盡量完整保留文件的所有屬性包括權(quán)限、時(shí)間戳、軟鏈接等。mv命令表面上是移動(dòng)實(shí)際也承擔(dān)了重命名的功能。mv oldname newname就是改名。這里有個(gè)比較隱蔽的坑如果你用mv把文件移動(dòng)到另一個(gè)文件系統(tǒng)上它其實(shí)會(huì)先復(fù)制再刪除速度可能會(huì)很慢。要快速移動(dòng)盡量保證源和目標(biāo)在同一個(gè)文件系統(tǒng)里。還有一個(gè)習(xí)慣問題我建議在覆蓋重要文件之前養(yǎng)成加-i參數(shù)的習(xí)慣這樣遇到同名文件會(huì)先問一句避免手滑覆蓋。刪除命令rm是必須時(shí)刻保持敬畏心的命令。rm -rf這三個(gè)字符組合在一起能瞬間清空一個(gè)目錄樹而且不會(huì)進(jìn)回收站。我見過有人想刪除一個(gè)臨時(shí)目錄結(jié)果少打了一個(gè)字母直接刪掉了上一級(jí)的正式目錄。我的經(jīng)驗(yàn)是第一刪除前先用ls看清楚要?jiǎng)h的是什么第二能不用-f就不用-f第三對(duì)重要數(shù)據(jù)優(yōu)先用rm -i讓系統(tǒng)逐個(gè)確認(rèn)。如果嫌煩可以設(shè)置一個(gè)別名讓rm默認(rèn)等于rm -i。2.3 查找文件的一招制敵查找文件是文件命令里含金量最高的一塊。圖形界面的搜索功能在文件數(shù)量少的時(shí)候還好用但一旦目錄層級(jí)深、文件名不規(guī)律就很難受了。find命令是我所有文件操作中調(diào)用頻率最高的之一。最簡單的用法是按文件名找find . -name *.log這條命令會(huì)在當(dāng)前目錄下遞歸查找所有以.log結(jié)尾的文件。注意-name是區(qū)分大小寫的如果不想?yún)^(qū)分用-iname。還可以按特征找文件。比如找大于100M的文件find /data -size 100M找7天前修改過的文件find . -mtime 7找目錄而不找文件find . -type d。這些組合起來非常靈活比如清理舊日志可以直接find /var/log -name *.log -mtime 30 -delete意思是“找到30天前修改的日志文件然后直接刪除”。find還有一個(gè)很常用的搭配是xargs。因?yàn)閒ind找出來的結(jié)果可能很多直接傳給某些命令會(huì)超出參數(shù)長度限制用xargs可以分批處理。例如find . -name *.tmp -print0 | xargs -0 rm -f這里的-print0和-0是為了應(yīng)對(duì)文件名里有空格的情況后面我會(huì)詳細(xì)講。如果你是想快速找一個(gè)已知名字的文件可以用locate它比find快得多因?yàn)樗菑南到y(tǒng)維護(hù)的索引庫里查的。但索引不是實(shí)時(shí)更新的剛創(chuàng)建的文件可能查不到需要先運(yùn)行updatedb更新索引。所以我的習(xí)慣是精確知道名字、索引較新用locate需要按復(fù)雜條件搜索用find。3. 批量處理實(shí)戰(zhàn)讓命令幫你干重復(fù)活文件操作真正的爆發(fā)力體現(xiàn)在批量處理上。一個(gè)文件的操作手動(dòng)做也不慢但一千個(gè)文件手動(dòng)做和命令做的差距就是天壤之別。這一節(jié)我會(huì)演示幾個(gè)最常用的批量場景。3.1 批量改名別再一個(gè)個(gè)雙擊批量改名的需求特別常見。比如圖片導(dǎo)出后叫IMG_001.jpg、IMG_002.jpg你想統(tǒng)一改成photo-2024-001.jpg或者一堆report.txt想全部改成report.md。這時(shí)候手動(dòng)一個(gè)個(gè)重命名不但慢還容易出錯(cuò)。最基本的思路是用 for 循環(huán)。在 bash 里可以這樣批量把.txt改成.mdfor f in *.txt; do mv $f ${f%.txt}.md done這段代碼的意思是循環(huán)每一個(gè).txt文件把文件名末尾的.txt去掉再拼上.md然后重命名。注意這里給$f加了雙引號(hào)這是一個(gè)非常重要的習(xí)慣。如果文件名里有空格不加引號(hào)就會(huì)被拆成多個(gè)參數(shù)導(dǎo)致命令出錯(cuò)。如果你用的是支持 Perl 版 rename 的系統(tǒng)批量改名的寫法更簡潔rename s/\.txt$/\.md/ *.txtrename的語法本質(zhì)上是一段正則表達(dá)式s/舊串/新串/表示替換。比如rename s/IMG_/photo-/ *.jpg可以把所有IMG_前綴替換成photo-。不過要注意不同系統(tǒng)自帶的rename版本不一樣有的系統(tǒng)里的rename是另一種簡單用法不一定支持這種正則。所以如果你在別的機(jī)器上運(yùn)行命令報(bào)錯(cuò)不要慌直接改用 for 循環(huán)最保險(xiǎn)。還有一個(gè)我常用的技巧改名前先預(yù)覽。先跑一條命令把結(jié)果打出來看看確認(rèn)無誤后再真正執(zhí)行。比如for f in *.txt; do echo mv $f ${f%.txt}.md; done這條命令只打印將要執(zhí)行的命令不會(huì)真正執(zhí)行。確認(rèn)沒問題后再把echo去掉或者在前面加上eval。這樣可以避免批量操作“一錯(cuò)錯(cuò)一片”的慘劇。3.2 壓縮打包的正確打開方式壓縮解壓是傳遞文件、備份數(shù)據(jù)的基本功。命令行里的壓縮工具比圖形界面那幾個(gè)“右鍵壓縮”功能強(qiáng)很多尤其是處理大量小文件的時(shí)候速度和選項(xiàng)都更可控。最常用的組合是tar。打包并壓縮tar czvf archive.tar.gz /path/to/dir參數(shù)拆解一下c表示創(chuàng)建歸檔z表示用 gzip 壓縮v表示顯示處理過程f表示指定歸檔文件名。所以這段命令的意思就是“把目錄打包并用 gzip 壓縮成 archive.tar.gz”。解壓縮的對(duì)應(yīng)命令是tar xzvf archive.tar.gz -C /target/dirx表示解包-C指定解壓到的目標(biāo)目錄。注意如果你不確定壓縮包里的文件結(jié)構(gòu)可以先不解壓用tar ztvf archive.tar.gz來列出歸檔里有哪些文件避免解壓出一堆文件散落在當(dāng)前目錄。如果你要排除某些文件或目錄用--exclude參數(shù)。比如備份目錄時(shí)不把臨時(shí)文件打進(jìn)去tar czvf backup.tar.gz --exclude*.tmp --excludecache/ /path/to/dir這個(gè)參數(shù)非常實(shí)用尤其是備份 Web 項(xiàng)目的node_modules或vendor目錄時(shí)可以直接排除掉讓壓縮包小很多。還有一種常見場景是跨平臺(tái)傳文件用zip。打包命令zip -r archive.zip /path/to/dir-r表示遞歸包含子目錄。解壓則用unzip archive.zip。如果文件特別大、想要更高的壓縮率可以用7z a -t7z archive.7z /path/to/dir但目標(biāo)機(jī)器上要裝有 7-Zip 才能解壓。我個(gè)人的經(jīng)驗(yàn)是Linux 之間傳遞優(yōu)先用tar和 Windows 協(xié)作傳給對(duì)方讓對(duì)方解壓優(yōu)先用zip兼容性最好。3.3 批量統(tǒng)計(jì)與內(nèi)容處理文件命令不只是管文件名還能處理文件內(nèi)容。這一塊對(duì)做日志分析、數(shù)據(jù)清洗的人特別有用。最簡單的是統(tǒng)計(jì)行數(shù)wc -l file.txt。想統(tǒng)計(jì)一個(gè)目錄下所有文件的總行數(shù)可以cat *.txt | wc -l。過濾內(nèi)容的首選是grep。比如從一份訪問日志里找出所有狀態(tài)碼為 500 的請求grep 500 access.log如果想統(tǒng)計(jì)有多少條加-cgrep -c 500 access.log。分組統(tǒng)計(jì)是sort和uniq的強(qiáng)項(xiàng)。比如現(xiàn)在有一個(gè)文件每一行是一個(gè) IP你想統(tǒng)計(jì)每個(gè) IP 出現(xiàn)次數(shù)并按次數(shù)排序sort ip.txt | uniq -c | sort -nr拆開看先排序讓相同 IP 排到一起再用uniq -c統(tǒng)計(jì)連續(xù)相同行的數(shù)量最后用sort -nr按數(shù)字倒序排列。這個(gè)組合是分析日志里“哪個(gè)來源訪問最多”的經(jīng)典套路。如果要做更復(fù)雜的字段切分用awk。比如訪問日志每一行格式是IP、時(shí)間、請求路徑、狀態(tài)碼字段之間用空格分隔。我想統(tǒng)計(jì)每個(gè)請求路徑的訪問量awk {print $3} access.log | sort | uniq -c | sort -nr這里$3表示按空格分隔后的第3個(gè)字段具體取第幾個(gè)取決于日志格式。awk的功能遠(yuǎn)不止這些它還可以做條件判斷、累加求和是真正的文本數(shù)據(jù)處理利器。我的建議是先記住awk {print $N}這個(gè)用法很多場景夠用了復(fù)雜需求再慢慢查。4. 權(quán)限、鏈接與安全邊界文件操作不只是“怎么把文件處理完”還有一個(gè)繞不開的主題權(quán)限。很多時(shí)候命令明明沒錯(cuò)卻報(bào)Permission denied原因就是權(quán)限不夠。理解權(quán)限模型能幫你省掉大量排查時(shí)間。4.1 權(quán)限模型與chmodLinux 和 macOS 的權(quán)限模型分三組文件屬主user、屬組group、其他用戶other。每組又分三種權(quán)限讀r、寫w、執(zhí)行x。用ls -l查看文件時(shí)前面那串-rwxr-xr--就是權(quán)限描述。權(quán)限可以用數(shù)字來表示這叫八進(jìn)制權(quán)限表示法。規(guī)則很簡單讀 r 是 4寫 w 是 2執(zhí)行 x 是 1。三者相加得到一個(gè)一位數(shù)。比如7 421表示讀寫執(zhí)行5 41表示讀和執(zhí)行4表示只讀。三個(gè)組依次填入就成了三位數(shù)比如754表示屬主有全部權(quán)限7屬組有讀和執(zhí)行權(quán)限5其他用戶只有讀權(quán)限4。修改權(quán)限用chmod。舉個(gè)例子把一個(gè)腳本改成屬主可讀寫執(zhí)行、屬組和他人只讀chmod 744 script.sh如果是給所有用戶加上執(zhí)行權(quán)限chmod x script.sh遞歸修改一個(gè)目錄下所有文件用chmod -R。這里我要提醒一個(gè)常見誤區(qū)目錄的“執(zhí)行權(quán)限”和文件的“執(zhí)行權(quán)限”含義不一樣。對(duì)于目錄執(zhí)行權(quán)限表示“能否進(jìn)入這個(gè)目錄”。所以如果你把某個(gè)目錄設(shè)成644別人可以讀取目錄列表但無法進(jìn)入也沒法打開目錄里的文件。換句話說目錄至少要有x權(quán)限才能被正常訪問。我第一次被這個(gè)問題坑的時(shí)候明明所有文件權(quán)限都正常但就是訪問不了最后排查發(fā)現(xiàn)是父目錄少了執(zhí)行權(quán)限。4.2 屬主變更與遞歸操作一個(gè)文件屬于哪個(gè)用戶、哪個(gè)組決定了它能被誰管理。修改命令是chown。比如把文件的所有者改成某個(gè)用戶chown user:group file.txtuser:group可以一起寫也可以只寫一半。如果只改屬主用chown user file.txt只改組可以用chgrp group file.txt。批量修改目錄及其下面所有文件的屬主加-Rchown -R user:group /path/to/dir這類操作在部署項(xiàng)目、遷移服務(wù)器時(shí)特別常見。我把源碼從一臺(tái)機(jī)器復(fù)制到另一臺(tái)機(jī)器后文件所有者經(jīng)常還是原來的賬號(hào)需要chown統(tǒng)一修正。要注意的是chown只有超級(jí)用戶或文件屬主才能執(zhí)行普通用戶想改成別人是做不到的這是系統(tǒng)安全的底線。4.3 軟鏈接和硬鏈接怎么選鏈接是文件系統(tǒng)里一個(gè)很重要、但又經(jīng)常被誤解的概念。最常見的是軟鏈接符號(hào)鏈接可以把它理解成 Windows 里的快捷方式。創(chuàng)建方式ln -s /original/file /path/to/link這里/original/file是真實(shí)文件/path/to/link是鏈接名。訪問鏈接就相當(dāng)于訪問原文件。用軟鏈接的最典型場景是程序版本切換。比如系統(tǒng)里裝了多個(gè)版本的程序當(dāng)前用到的版本放在current軟鏈接里要切換版本只需要重新指定軟鏈接指向不用改各種配置。硬鏈接就不同了。它不像快捷方式而是兩個(gè)文件名共享同一個(gè)存儲(chǔ)數(shù)據(jù)區(qū)域。創(chuàng)建方式ln /original/file /path/to/hardlink硬鏈接有幾個(gè)限制不能跨文件系統(tǒng)不能指向目錄。但它有個(gè)優(yōu)勢只要還有一個(gè)硬鏈接存在數(shù)據(jù)就不會(huì)被刪除。我見過有人用硬鏈接來給重要文件做“瞬時(shí)備份”占用空間幾乎為零效果卻很好。什么時(shí)候用哪個(gè)我的經(jīng)驗(yàn)是日常使用、需要明確指向一個(gè)目標(biāo)文件、路徑經(jīng)常變化選軟鏈接想給同一份數(shù)據(jù)做多個(gè)名字、并且確認(rèn)數(shù)據(jù)不會(huì)被誤刪選硬鏈接。兩個(gè)命令都值得記住但在實(shí)際工作中軟鏈接的使用頻率高得多。5. 常見問題與排查技巧這一部分整理的是我這些年實(shí)際操作中踩過、看過別人踩過的坑。每個(gè)問題都配了排查思路和解決辦法建議收藏起來遇到類似情況直接對(duì)照。5.1 文件名帶空格怎么辦這是新手遇到的第一道坎。命令行里空格默認(rèn)是參數(shù)分隔符。一個(gè)叫my report.txt的文件如果你直接寫cat my report.txt命令會(huì)認(rèn)為你傳了兩個(gè)參數(shù)給catmy和report.txt然后報(bào)錯(cuò)“文件不存在”。解決辦法有兩種。第一種是加引號(hào)cat my report.txt cat my report.txt第二種是用轉(zhuǎn)義符反斜杠cat my\ report.txt在腳本和循環(huán)里一定要把變量用雙引號(hào)包起來。比如前面提到過的for f in *.txt; do mv $f ${f%.txt}.md done如果這里寫成mv $f ...而沒有引號(hào)一旦文件名里帶空格命令就會(huì)執(zhí)行失敗甚至執(zhí)行錯(cuò)誤。這是一個(gè)非常典型且容易引發(fā)批量事故的細(xì)節(jié)??崭駟栴}還影響find與xargs的配合。如果文件名帶空格簡單的find . -name *.txt | xargs rm同樣會(huì)出錯(cuò)因?yàn)閤args默認(rèn)把空格當(dāng)作分隔符。正確的做法是讓find輸出以空字符結(jié)尾并讓xargs也按空字符切分find . -name *.txt -print0 | xargs -0 rm-print0和-0是配套使用的。這個(gè)寫法看起來嚇人但實(shí)際用起來非常穩(wěn)建議直接記下來。5.2 通配符的認(rèn)知誤區(qū)通配符*、?在命令行里很常用但有不少隱含規(guī)則。第一個(gè)誤區(qū)*不會(huì)匹配以.開頭的隱藏文件。比如你輸入rm *并不會(huì)刪除所有隱藏文件。這其實(shí)是個(gè)安全設(shè)計(jì)但如果你沒有意識(shí)到可能會(huì)以為文件沒刪干凈或者反過來用了rm .*又誤刪了大量隱藏配置。所以rm .*這種寫法要極度小心最好先用ls .*看看會(huì)匹配到什么。第二個(gè)誤區(qū)當(dāng)匹配到的文件數(shù)量特別多時(shí)命令可能會(huì)報(bào)Argument list too long。比如某個(gè)目錄下有幾十萬個(gè)文件你執(zhí)行rm *.logshell 會(huì)把所有文件名展開成參數(shù)超過系統(tǒng)參數(shù)長度上限命令無法執(zhí)行。這種時(shí)候不要慌改用findfind . -name *.log -deletefind是逐條處理的不會(huì)把所有文件名一次性壓到參數(shù)里所以大規(guī)模刪除更安全。第三個(gè)誤區(qū)通配符是在 shell 展開的而不是在命令內(nèi)部。這意味著如果你用引號(hào)把*.log包起來通配符就不會(huì)被展開命令會(huì)去尋找一個(gè)真正叫*.log的文件。有時(shí)候你明明有匹配的文件命令卻說找不到可能就是引號(hào)的問題。所以當(dāng)你看到find . -name *.log時(shí)-name后面的引號(hào)是刻意保留通配符的這里的規(guī)則正好和前面相反需要根據(jù)命令語義來理解。5.3 誤刪文件的后悔藥命令行刪除不走回收站這是很多人第一次意識(shí)到這一點(diǎn)時(shí)驚出一身冷汗的時(shí)刻。rm -rf過去的文件基本找不回來。所以我強(qiáng)烈建議你做兩件事。第一給rm設(shè)置安全別名。在 bash 的配置文件里寫alias rmrm -i這樣每次刪除文件前都會(huì)詢問確認(rèn)。剛開始可能覺得煩但關(guān)鍵時(shí)刻能救命。第二安裝并使用回收站工具比如trash-cli。它可以把文件移動(dòng)到系統(tǒng)回收站目錄而不是直接刪除。用法和rm很相似比如trash file.txt、trash-restore可以恢復(fù)。雖然需要額外安裝但對(duì)于經(jīng)常在命令行里操作文件的人這個(gè)投資非常值。我還想強(qiáng)調(diào)一個(gè)操作習(xí)慣不要直接在命令里拼rm -rf加變量路徑。比如rm -rf /home/user/$temp_dir如果$temp_dir因?yàn)槟撤N原因沒有賦值解析后就是rm -rf /home/user/這等于把整個(gè)用戶目錄清空。正確做法是在執(zhí)行刪除前先檢查變量是否為空或者在刪除命令前加上條件判斷。哪怕多寫兩行也比一次毀滅性事故強(qiáng)。如果真的誤刪了第一反應(yīng)是立刻停止向該磁盤寫入任何新數(shù)據(jù)。然后嘗試用extundelete之類的恢復(fù)工具。說實(shí)話恢復(fù)成功率并不高所以最重要的防線還是備份和預(yù)防。我現(xiàn)在的習(xí)慣是重要目錄每天自動(dòng)備份命令行刪除前手動(dòng)確認(rèn)一次雙重保險(xiǎn)。5.4 文件亂碼的排查思路中文環(huán)境下的文件操作亂碼問題幾乎人人都遇到過。尤其是從 Windows 拷過來的文件經(jīng)常出現(xiàn)打開之后滿屏“錕斤拷”或者“”。排查亂碼的第一步是搞清楚文件的編碼格式。用file -i可以查看file -i filename.txt輸出結(jié)果里會(huì)帶charsetiso-8859-1、charsetutf-8或者charsetgb18030之類的信息。如果是老舊的編碼需要用iconv轉(zhuǎn)成 UTF-8iconv -f GBK -t UTF-8 old.txt new.txt這里-f是源編碼-t是目標(biāo)編碼。注意轉(zhuǎn)換結(jié)果是輸出到標(biāo)準(zhǔn)輸出所以要重定向到一個(gè)新文件直接iconv old.txt不會(huì)原地修改。還有一種更隱蔽的亂碼問題文件內(nèi)容沒問題但文件名本身是亂碼。尤其是從壓縮包里解壓出來或者在不同系統(tǒng)間傳輸后文件名可能會(huì)變成一串看不懂的字符。處理辦法是用convmv工具它可以批量轉(zhuǎn)換文件名的編碼convmv -f GBK -t UTF-8 --notest *.jpg--notest表示真正執(zhí)行轉(zhuǎn)換而不是只預(yù)覽。如果不加它只會(huì)顯示可能的改動(dòng)。這里我想多說一句亂碼的根本原因是編碼不一致所以最佳方案是預(yù)防養(yǎng)成新建文件、保存文件都使用 UTF-8 的習(xí)慣接收外部文件時(shí)先查編碼再做處理。另外一個(gè)和亂碼很像、但本質(zhì)不同的問題是換行符。Windows 的文件行尾是\r\nLinux 是\n。這樣會(huì)導(dǎo)致文件在 Linux 下顯示時(shí)每行末尾多一個(gè)看不見的符號(hào)腳本處理時(shí)還可能引發(fā)報(bào)錯(cuò)。處理方式是使用dos2unix工具一條命令搞定dos2unix filename.txt這些工具在絕大多數(shù) Linux 發(fā)行版里都可以通過包管理器安裝。如果你不想裝也可以用sed -i s/\r$// filename.txt達(dá)到類似效果。說句心里話“文件的應(yīng)用命令”不是一個(gè)需要刻意背的東西。我每次接觸新環(huán)境也是邊查邊用查多了自然就記住了。真正重要的是建立起“文件操作可以用命令高效完成”的意識(shí)。很多人覺得命令行難其實(shí)是沒遇到足夠多的場景。等你有幾百個(gè)文件要處理、幾十臺(tái)機(jī)器要維護(hù)、一屋子日志要看的時(shí)候自然會(huì)愿意花這十幾分鐘把這些命令練熟。我的最后一條建議是把你最常用的幾條命令寫在一個(gè)文本文件里放桌面或掛在終端配置里當(dāng)備忘遇到不確定的隨時(shí)翻。這比死記硬背高效得多也更能讓你在真正需要時(shí)想起它們。