原文連結:File it away
有時你會因一個檔案而迷惑,這個檔案可能是在你的檔案夾中的一個未知類型的檔案,它可能是你的父母或者客戶給你的。不幸的是,你不知道它到底是一種什麼樣的檔案。在Mac上檔案是不帶有拓展名的,是以可能并沒有足夠的資訊來告訴你“Flongnozzle-2012”到底包含了什麼内容。然而終端(Terminal)可以為你提供一些便利,你可以使用一些内嵌的指令行工具來幫助你鑒别檔案。
識别檔案内容
對于這種情況,file指令恰好是我所需要的。file指令可以檢測一個檔案的内容然後試圖去弄清楚它是什麼。
1 2 | |
當然,這其實是Objective-C檔案,不過終端已經非常接近了,終端将其鑒别為一個内有代碼的檔案。“等等,MarkD(注:作者),它僅僅看下檔案的拓展名不就行了嗎?”file指令也支援這種情況,不過拓展名并不是必須的:
1 2 3 | |
沒有檔案拓展名,不過我們依然鑒别出了這個檔案是什麼。将file指令指向一個可能包含可執行代碼的檔案或目錄,它會告訴你其内在的結構:
1 2 | |
你可能會說,如果你有一個體積龐大的二進制檔案(例如,原生的App)怎麼辦,下面是辦法:
1 2 3 4 | |
将file指向一個圖檔檔案來看看圖檔的一些資訊:
1 2 | |
哦等等,這裡有一個終端的使用小技巧:将檔案的圖示從Finder中拖入終端視窗,這就相當于将你拖動的這個檔案或檔案夾的完整路徑粘貼進去了。
進一步探索
有時file也不會讓你滿意,或者你可能想要知道關于檔案的更多資訊。一般來說,你總是可以通過QuickLook在Finder中浏覽一下檔案,如果這樣不起作用,那麼你可以使用hexdump指令來看看出檔案的位元組數,也可以傳入參數-c來看看翻譯成ASCII碼之後的資訊。
例如,回到我們之前的那個圖檔檔案:
1 2 3 4 5 6 | |
在展示出來的資料區并沒有太多有用資訊,但是你可以看到它是PNG類型的,這已經是比較有用了,有些檔案還含有更多字元串類型的内容,下面是對一個從Reason數位音頻工作室獲得的更新檔檔案使用hexdump指令得到的資訊:
1 2 3 4 5 6 7 8 9 10 11 | |
如果你之前用過Reason,術語“CV Values”和“DDL Digital Delay Line”你一定不會陌生。
strings指令可以從檔案中得到像字元串一樣的位元組序列:
1 2 3 4 5 6 7 8 9 10 | |
屬性值
屬性清單(Property lists)是Mac和iOS系統上的一種标準類型的檔案,将一些可以預知類型的資料有結構地組織起來就構成了我們的plist檔案。在該系統上,一般你看到的屬性清單檔案都是被壓縮成二進制格式的檔案,這樣在讀取時會更快。使用者的偏好設定就被存儲為plist檔案:
1 2 3 4 | |
不幸的是,這個壓縮之後的plist檔案是一種非常難讀的檔案:
1 2 3 4 5 6 7 8 9 10 | |
幸運的是,有一個工具plutil指令能将這樣二進制形式的資料轉換為更接近與人類可讀語言的形式:
(“!$”快捷鍵用來擷取上一條指令中得最後一個參數)
Spotlight
在解讀一個特定檔案方面,OS可能做得比你想象得更好。Spotlight的工作就是為磁盤上的檔案編制索引,通過查詢中繼資料來讓本地搜尋更友善快捷。你可以通過mdls指令來擷取這個中繼資料,是以你能夠問問Spotlight對于這個檔案都知道些什麼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
這裡mdls告訴你這個檔案是Objective-C代碼的源檔案,同時還有其他相同類型的辨別符來描述資料,這确實是代碼的源檔案,并且是文本編輯格式。當然也有一些有趣的資料,例如這個檔案到底在磁盤上占據着多少空間,以及這個檔案由多少位元組組成。
加載服務(Launch Services)
另一個維護系統資料庫資訊的工具是加載服務,它決定着哪個應用會打開哪個檔案。輕按兩下一個檔案來打開它?Finder會去詢問加載服務。在指令行使用open指令來打開檔案?系統也會去詢問加載服務,由它來辨識到底由誰去打開檔案。
lsappinfo指令就是一個使用加載服務(當然還有核心應用服務,Core Application Services)的工具,它能給你一些關于現在正在運作的應用的資訊。這與辨識檔案到底是什麼無關,但是有了它,你就能了解到一些很cool的資訊。試一下使用lsappinfo sharedmemory指令來獲得共享記憶體的資訊。或者使用lsappinfo visibleProcessList指令列出一組現可見的應用程式(順序為按視窗從前到後)。
要擷取加載服務的其他特性可以通過API,或者是lsregister。其中lsregister算是一個衆所周知但卻非官方的工具了。lsregister在LaunchServices架構下的Support目錄内,而LaunchServices架構又被包含在CoreServices架構中。在你的機器上,很可能是下面這樣的路徑:
1 | |
lsregister主要被用于在OS系統上注冊一個檔案,這個檔案将會由特定的應用程式來處理。不過你可以dump它的資料庫來檢視相關資訊,使用:
1 | |
(要運作該指令,你需要擴充你的PATH,加入Support目錄)。
這條指令産生了大概61000行輸出,是以這對于一個日常教程來說就有些太笨重了,不過浏覽一下也是挺有趣的。
還有一些有用的功能來自于一個調用:LSCopyApplicationURLsForURL。給這個調用傳入一個檔案的路徑作為參數,它會傳回一組可以處理該檔案的應用集合。它有不同的查詢模式,像“能打開這個檔案的所有的應用程式有哪些?”,或者“能編輯這個檔案的所有應用程式有哪些?”加載服務并不像file指令一樣去内探這個檔案的結構。取而代之的是,它利用檔案的拓展名、源代碼、模糊比對來找出合适的應用。
這裡有一個小工具,它需要在指令行傳入一個檔案名。通過調用LSCopyApplicationURLsForURL,列印出比對出來的應用程式的數組。你可以在這裡找到這個源代碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
最有趣的部分是這裡用的是realpath()庫,通過調用它來将指令行參數中的檔案名轉換為完整路徑(是以你不用擔心如果使用者到底傳入的是一個相對路徑,還是一個絕對路徑,還是一個帶~的路徑),然後将它傳入LSCopyApplicationURLsForURL,這裡還使用了kLSRolesEditor,因為它可以傳回最合理的一組應用程式。有時候選的應用程式也能給你一些線索來判斷這個檔案到底是什麼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
不幸的是,它并不能解決“Flongnozzle”是什麼的問題,因為這個檔案沒有拓展名或者其他有用的檔案類型的資訊。
其他工具
可用的指令行工具集非同尋常得多,是以我很可能落下了一個或者兩個或者更多其他的工具來幫助你辨識一個未知檔案。如果你有一個非常喜歡的小技巧,請留下一條評論!
翻譯:Mr_cyz,于1-19日首發于CocoaChina