识别Mac电脑上文件的命令行技巧

有时你会因一个文件而迷惑,这个文件可能是在你的文件夹中的一个未知类型的文件,它可能是你的父母或者客户给你的。不幸的是,你不知道它到底是一种什么样的文件。在Mac上文件是不带有拓展名的,所以可能并没有足够的信息来告诉你“Flongnozzle-2012”到底包含了什么内容。然而终端(Terminal)可以为你提供一些便利,你可以使用一些内嵌的命令行工具来帮助你鉴别文件。

识别文件内容

对于这种情况,file命令恰好是我所需要的。file指令可以检测一个文件的内容然后试图去弄清楚它是什么。

当然,这其实是Objective-C文件,不过终端已经非常接近了,终端将其鉴别为一个内有代码的文件。“等等,MarkD(注:作者),它仅仅看下文件的拓展名不就行了吗?”file命令也支持这种情况,不过拓展名并不是必须的:

没有文件拓展名,不过我们依然鉴别出了这个文件是什么。将file命令指向一个可能包含可执行代码的文件或目录,它会告诉你其内在的结构:

你可能会说,如果你有一个体积庞大的二进制文件(例如,原生的App)怎么办,下面是办法:

将file指向一个图片文件来看看图片的一些信息:

哦等等,这里有一个终端的使用小技巧:将文件的图标从Finder中拖入终端窗口,这就相当于将你拖动的这个文件或文件夹的完整路径粘贴进去了。

进一步探索

有时file也不会让你满意,或者你可能想要知道关于文件的更多信息。一般来说,你总是可以通过QuickLook在Finder中浏览一下文件,如果这样不起作用,那么你可以使用hexdump命令来看看出文件的字节数,也可以传入参数-c来看看翻译成ASCII码之后的信息。

例如,回到我们之前的那个图片文件:

在展示出来的数据区并没有太多有用信息,但是你可以看到它是PNG类型的,这已经是比较有用了,有些文件还含有更多字符串类型的内容,下面是对一个从Reason数码音频工作室获得的补丁文件使用hexdump指令得到的信息:

如果你之前用过Reason,术语“CV Values”和“DDL Digital Delay Line”你一定不会陌生。

strings命令可以从文件中得到像字符串一样的字节序列:

属性值

属性列表(Property lists)是Mac和iOS系统上的一种标准类型的文件,将一些可以预知类型的数据有结构地组织起来就构成了我们的plist文件。在该系统上,一般你看到的属性列表文件都是被压缩成二进制格式的文件,这样在读取时会更快。用户的偏好设置就被存储为plist文件:

不幸的是,这个压缩之后的plist文件是一种非常难读的文件:

幸运的是,有一个工具plutil指令能将这样二进制形式的数据转换为更接近与人类可读语言的形式:

(“!$”快捷键用来获取上一条指令中得最后一个参数)

Spotlight

在解读一个特定文件方面,OS可能做得比你想象得更好。Spotlight的工作就是为磁盘上的文件编制索引,通过查询元数据来让本地搜索更方便快捷。你可以通过mdls命令来获取这个元数据,所以你能够问问Spotlight对于这个文件都知道些什么:

这里mdls告诉你这个文件是Objective-C代码的源文件,同时还有其他相同类型的标识符来描述数据,这确实是代码的源文件,并且是文本编辑格式。当然也有一些有趣的数据,例如这个文件到底在磁盘上占据着多少空间,以及这个文件由多少字节组成。

加载服务(Launch Services)

另一个维护系统数据库信息的工具是加载服务,它决定着哪个应用会打开哪个文件。双击一个文件来打开它?Finder会去询问加载服务。在命令行使用open指令来打开文件?系统也会去询问加载服务,由它来辨别到底由谁去打开文件。

lsappinfo指令就是一个使用加载服务(当然还有核心应用服务,Core Application Services)的工具,它能给你一些关于现在正在运行的应用的信息。这与辨别文件到底是什么无关,但是有了它,你就能了解到一些很cool的信息。试一下使用lsappinfo sharedmemory命令来获得共享内存的信息。或者使用lsappinfo visibleProcessList命令列出一组现可见的应用程序(顺序为按窗口从前到后)。

要获取加载服务的其他特性可以通过API,或者是lsregister。其中lsregister算是一个众所周知但却非官方的工具了。lsregister在LaunchServices框架下的Support目录内,而LaunchServices框架又被包含在CoreServices框架中。在你的机器上,很可能是下面这样的路径:

lsregister主要被用于在OS系统上注册一个文件,这个文件将会由特定的应用程序来处理。不过你可以dump它的数据库来查看相关信息,使用:

(要运行该指令,你需要扩展你的PATH,加入Support目录)。

这条指令产生了大概61000行输出,因此这对于一个日常教程来说就有些太笨重了,不过浏览一下也是挺有趣的。

还有一些有用的功能来自于一个调用:LSCopyApplicationURLsForURL。给这个调用传入一个文件的路径作为参数,它会返回一组可以处理该文件的应用集合。它有不同的查询模式,像“能打开这个文件的所有的应用程序有哪些?”,或者“能编辑这个文件的所有应用程序有哪些?”加载服务并不像file指令一样去内探这个文件的结构。取而代之的是,它利用文件的拓展名、源代码、模糊匹配来找出合适的应用。

这里有一个小工具,它需要在命令行传入一个文件名。通过调用LSCopyApplicationURLsForURL,打印出匹配出来的应用程序的数组。你可以在这里找到这个源代码。

最有趣的部分是这里用的是realpath()库,通过调用它来将命令行参数中的文件名转换为完整路径(所以你不用担心如果用户到底传入的是一个相对路径,还是一个绝对路径,还是一个带~的路径),然后将它传入LSCopyApplicationURLsForURL,这里还使用了kLSRolesEditor,因为它可以返回最合理的一组应用程序。有时候选的应用程序也能给你一些线索来判断这个文件到底是什么。

不幸的是,它并不能解决“Flongnozzle”是什么的问题,因为这个文件没有拓展名或者其他有用的文件类型的信息。

其他工具

可用的命令行工具集非同寻常得多,因此我很可能落下了一个或者两个或者更多其他的工具来帮助你辨别一个未知文件。如果你有一个非常喜欢的小技巧,请留下一条评论!

收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部