file命令_Linux file命令:檢視檔案資訊或型別

2020-07-16 10:04:30
有人的地方,就有江湖。人往往是最難揣摩的。如果有一面神奇的魔鏡能看出一個人的內心,世界會不會變得更加美好呢?Linux 的世界裡,file 就是這樣一面魔鏡,它可以看到每個檔案的內心。file 命令可以識別出檔案的型別和編碼格式,這是其他命令所做不到的。

檢視檔案型別

開門見山,我們直接用 file 這面魔鏡來看看檔案的“內心”。
#不加任何選項, 直接檢視poetry檔案
[[email protected] ~]$ file poetry.txt
poetry.txt: ASCII text
使用不帶任何選項的 file 命令,即可檢視指定檔案的型別資訊。在上面的例子中可以看出 poetry.txt 的檔案型別為 text,編碼格式為 ASCII。


#使用-b選項來檢視poetry檔案
[[email protected] ~]$ file -b poetry.txt
ASCII text
上面的例子中,我們使用了-b選項,可以使 file 命令的輸出不出現檔名,只顯示檔案格式以及編碼。

#使用-i選項來檢視poetry檔案
[[email protected] ~]$ file -i poetry.txt
poetry.txt: text/plain; charset=us-ascii
上面的例子中,我們使用了-i選項,可以輸出檔案的 MIME 型別字串。

小科普,MIME 型別,即 Multipurpose Internet Mail Extensions,稱為多用途網際網路郵件擴充套件型別,用來標識和記錄檔案的開啟方式,一些常見的型別包括:
  • text/plain:普通文字。
  • text/html:HTML文字。
  • application/pdf:PDF文件。
  • application/msword:Word文件。
  • image/png:PNG圖片。
  • mage/jpeg:JPEG圖片。
  • application/x-tar:TAR檔案。
  • application/x-gzip:GZIP檔案。

設定輸出分隔符

從上面的例子可以看出,file 命令的輸出格式是:
檔名:檔案型別和編碼格式

如果希望將中間的分隔符由冒號(:)改成其他符號,則可以使用-F選項來實現。
[[email protected] ~]$ file poetry.txt
poetry.txt: ASCII text
 
[[email protected] ~]$ file -F "=>" poetry.txt
poetry.txt=> ASCII text

有些同學會問,這樣的功能有何意義呢?在一些自動化檔案分析的指令碼中,開發者為了避免分隔符和普通字元重複而造成誤解析的情況,通常是會手工調整間隔符的。

檢視軟連結檔案

file 命令能檢視所有檔案的型別資訊,那麼問題來了,對於一個軟連結檔案,file 命令是返回軟連結檔案本身的型別資訊,還是返回軟連結所指向的目標檔案的型別資訊呢?讓我們通過試驗得出結論吧:
#新建一個軟連結檔案
[[email protected] ~]$ ln -s poetry.txt poetry_s.txt

 
#通過file命令檢視軟連結檔案
[[email protected] ~]$ file poetry_s.txt
poetry_s.txt: symbolic link to `poetry.txt'
 
#使用-L選項來檢視軟連結檔案
[[email protected] ~]$ file -L poetry_s.txt
poetry_s.txt: ASCII text

試驗是找到真相的最好方法。通過上面的範例,我們已經很清楚地看到了:
  • 如果通過 file 命令直接檢視軟連結檔案,則檢視的就是軟連結檔案本身的資訊。
  • 如果使用-L選項來檢視軟連結檔案,則檢視的是軟連結指向的目標檔案的資訊。

按照清單去工作

如果我們需要用 file 命令檢視大量檔案的型別資訊,恰好這些檔案的名稱都被儲存在了一個文字檔案中,那麼-f選項就派上用場了。我們可以通過-f選項來指定這個文字檔案,file 命令就會乖乖地去逐個檢視每一個檔案的型別資訊,範例如下:
#檔案中含有三個待查檔案, 我們故意設定了一個不存在的檔案, 位於最後一個
[[email protected] ~]$ cat poetry_list.txt
/root/book/poetry.txt
/root/book/poetry_s.txt
Nothing.txt
 
#使用-f選項執行file命令
[[email protected] ~]$ file -f poetry_list.txt
/root/book/poetry.txt:   ASCII text
/root/book/poetry_s.txt: symbolic link to `poetry.txt'
Nothing.txt: ERROR: cannot open `Nothing.txt ' (No such file or directory)

在上面的例子中,poetry_list.txt 包含了 3 行內容:
  • poetry.txt。
  • 指向poetry.txt的軟連結poetry_s.txt。
  • Nothing.txt,一個明顯不存在的檔案。

從結果可以看出,前兩個如期輸出了型別資訊,最後一個也如期報了錯誤。

-z 選項,想說愛你不容易

一次偶然的機會,我在 man file 中發現了-z選項,原文解釋是“Try to look inside compressed files”,看來 file 還可以檢視壓縮檔案內部的檔案。那為什麼要用“Try to”這樣的字樣呢,為了弄明白這個細節,於是,我的試驗開始了。

第一輪試驗開始,我們先來試驗“一個未經壓縮的 tar 包”:
#製作一個未經壓縮的tar包
[[email protected] ~]$ tar -cvf poetry.tar poetry.txt poetry_s.txt
poetry.txt
poetry_s.txt
 
#嘗試使用-z選項
[[email protected] ~]$ file -z poetry.tar
poetry.tar: POSIX tar archive (GNU)

似乎並不盡如人意,file 只是看出 poetry.tar 是一個 tar 包,並沒有深入到 tar 包內部,第一輪試驗宣告失敗。

馬上進入第二輪試驗,我們看看一個經過 gzip 壓縮過的 tar 包情況如何?
#製作一個tar.gz包
[[email protected] ~]$ tar -czvf poetry.tar.gz poetry.txt poetry_s.txt
poetry.txt
poetry_s.txt
 
#使用-z選項檢視
[[email protected] ~]$ file -z poetry.tar.gz
poetry.tar.gz: POSIX tar archive (GNU) (gzip compressed data, from Unix, last modified: Tue Mar  1 17:43:59 2016)

輸出的資訊稍微豐富了一些,但還是停留在 tar 包的檔案型別的層面,仍然沒有窺探到裡面的 poetry.txt 和 poetry_s.txt 檔案。第二輪試驗也宣告失敗。

那 bzip2 壓縮的 tar 包是否 OK 呢?我們又趕快進入了第三輪試驗。
#製作一個.tar.bz2檔案
[[email protected] ~]$ tar -cjvf poetry.tar.bz2 poetry.txt poetry_s.txt
poetry.txt
poetry_s.txt
 
#使用-z選項檢視
[[email protected] ~]$ file -z poetry.tar.bz2
poetry.tar.bz2: POSIX tar archive (GNU) (bzip2 compressed data, block size = 900k)

如你所見,第三輪試驗仍然是失敗的。我已經開始懷疑人生了。信念讓我堅持,不能服輸。哈哈,就這樣,我們再次踏上征程。我懷疑file只能窺探到單個檔案壓縮的情況,於是,第四輪試驗開始了。
#製作一個只包含1個檔案的bz2檔案
[[email protected] ~]$ bzip2 -c poetry.txt > poetry.bz2
 
#使用-z選項檢視
[[email protected] ~]$ file -z poetry.bz2
poetry.bz2: ASCII text (bzip2 compressed data, block size = 900k)

結果依然讓我失望,這到底是要鬧哪樣啊?到了這步田地,也就剩下單個 gzip 壓縮檔案的情況沒有嘗試了,我再碰碰運氣吧,如果-z選項還是不能如願地顯示壓縮檔案包含檔案的型別資訊,我就打算給 file 的作者寫郵件投訴了。於是,第五輪試驗開始了。
#製作一個僅包含1個檔案的gz檔案
[[email protected] ~]$ gzip -c poetry.txt > poetry.gz
 
#嘗試用-z選項檢視, 竟然查出結果了, 看到了ASCII text字樣
[[email protected] ~]$ file -z poetry.gz
poetry.gz: ASCII text (gzip compressed data, was "poetry.txt", from Unix, last modified: Tue Mar  1 19:01:22 2016)
 
#再試試沒有-z選項的情況, 確實沒有探測出ASCII text型別
[[email protected] ~]$ file poetry.gz
poetry.gz: gzip compressed data, was "poetry.txt", from Unix, last modified: Tue Mar  1 19:01:22 2016
終於,終於,我們終於成功了,我們通過試驗找到了答案。

直到這步我們才知道,man 中-z選項的解釋雖然是“Try to look inside compressed files”,但其實只支援對 gzip 包內部檔案的窺探,而對於 tar、tar.gz、tar.bz2 和 bz2 包全部都不支援。

大膽猜測,file 的作者可能是迫於開發時間的壓力,僅僅支援了 gzip 的情況,但是又不希望未來僅支援這一種壓縮型別,因此寫上“Try to”,為日後的擴充套件留下了可能性。

最後,我要和 file 的作者說句話,你這樣使用“Try to”和使用者捉迷藏,以後還能一起愉快地玩耍麼?