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

原文链接:File it away

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

识别文件内容

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


1

2

% file launchHandler.m

launchHandler.m: ASCII C++ program text

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


1

2

3

% cp launchHandler.m splunge

% file splunge

splunge: ASCII C++ program text

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


1

2

% file /bin/ls

/bin/ls: Mach-O 64-bit executable x86_64

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


1

2

3

4

% file /Applications/Reason/Reason.app/Contents/MacOS/Reason

Reason.app/Contents/MacOS/Reason: Mach-O universal binary with 2 architectures

Reason.app/Contents/MacOS/Reason (for architecture i386): Mach-O executable i386

Reason.app/Contents/MacOS/Reason (for architecture x86_64): Mach-O 64-bit executable x86_64

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


1

2

% file Flongnozzle-2012

Flongnozzle-2012: PNG image data, 1932 x 904, 8-bit/color RGB, non-interlaced

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

进一步探索

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

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


1

2

3

4

5

6

% hexdump -C Flongnozzle-2012 | head

00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|

00000010  00 00 07 8c 00 00 03 88  08 02 00 00 00 a2 e0 9b  |................|

00000020  61 00 00 0c 45 69 43 43  50 49 43 43 20 50 72 6f  |a...EiCCPICC Pro|

00000030  66 69 6c 65 00 00 48 0d  ad 57 77 54 53 c9 17 be  |file..H..WwTS...|

00000040  af 24 81 90 84 12 88 80  94 d0 9b 28 bd 4a ef 82  |.$.........(.J..|

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


1

2

3

4

5

6

7

8

9

10

11

% hexdump -C CV-Spy--md.cmb

00000000  46 4f 52 4d 00 00 03 d8  50 54 43 48 43 41 54 20  |FORM....PTCHCAT |

00000010  00 00 00 04 52 45 46 53  43 4f 49 4e 00 00 00 06  |....REFSCOIN....|

00000020  bc 01 00 00 00 01 43 41  54 20 00 00 00 fc 44 45  |......CAT ....DE|

00000030  56 4c 46 4f 52 4d 00 00  00 f0 44 45 56 49 44 45  |VLFORM....DEVIDE|

00000040  53 43 00 00 00 47 bc 02  01 00 00 07 00 00 00 10  |SC...G..........|

00000050  00 00 00 12 43 56 20 56  61 6c 75 65 73 20 28 30  |....CV Values (0|

00000060  2d 3e 32 35 36 29 00 00  00 00 00 00 00 00 00 00  |->256)..........|

00000070  00 00 16 44 44 4c 20 44  69 67 69 74 61 6c 20 44  |...DDL Digital D|

00000080  65 6c 61 79 20 4c 69 6e  65 00 00 00 04 00 50 41  |elay Line.....PA|

...

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

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


1

2

3

4

5

6

7

8

9

10

% strings CV-Spy--md.cmb

FORM

PTCHCAT

REFSCOIN

CAT

DEVLFORM

DEVIDESC

CV Values (0->256)

DDL Digital Delay Line

...

属性值

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


1

2

3

4

% pwd

/Users/markd/Library/Preferences

% file com.apple.iphonesimulator.plist

com.apple.iphonesimulator.plist: Apple binary property list

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


1

2

3

4

5

6

7

8

9

10

% hexdump -C com.apple.iphonesimulator.plist

00000000  62 70 6c 69 73 74 30 30  dc 01 02 03 04 05 06 07  |bplist00........|

00000010  08 09 0a 0b 0c 0d 0e 0f  10 11 12 13 14 15 16 17  |................|

00000020  18 5e 53 69 6d 75 6c 61  74 65 44 65 76 69 63 65  |.^SimulateDevice|

00000030  5f 10 2f 4e 53 57 69 6e  64 6f 77 20 46 72 61 6d  |_./NSWindow Fram|

00000040  65 20 69 50 68 6f 6e 65  53 69 6d 75 6c 61 74 6f  |e iPhoneSimulato|

00000050  72 57 69 6e 64 6f 77 2e  32 2e 30 2e 37 35 30 30  |rWindow.2.0.7500|

00000060  30 30 5f 10 2f 4e 53 57  69 6e 64 6f 77 20 46 72  |00_./NSWindow Fr|

00000070  61 6d 65 20 69 50 68 6f  6e 65 53 69 6d 75 6c 61  |ame iPhoneSimula|

...

幸运的是,有一个工具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 launchHandler.m

kMDItemContentCreationDate     = 2014-07-02 19:22:02 +0000

kMDItemContentModificationDate = 2014-07-02 19:23:58 +0000

kMDItemContentType             = "public.objective-c-source"

kMDItemContentTypeTree         = (

    "public.objective-c-source",

    "public.source-code",

    "public.plain-text",

    "public.text",

    "public.data",

    "public.item",

    "public.content"

)

...

kMDItemKind                    = "Objective-C Source"

kMDItemLastUsedDate            = 2014-07-02 19:32:46 +0000

kMDItemLogicalSize             = 1443

kMDItemPhysicalSize            = 4096

kMDItemUseCount                = 2

kMDItemUsedDates               = (

    "2014-07-02 10:00:00 +0000"

这里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

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister

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


1

% lsregister -dump > services-db.txt

(要运行该指令,你需要扩展你的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

@import Foundation;

@import CoreServices;

// clang -g -fobjc-arc -fmodules launchHandler.m -o launchHandler

int main (int argc, const char *argv[]) {

    // Rudimentary argument checking.

    if (argc != 2) {

        printf ("usage: %s filename\n", argv[0]);

        return -1;

    }

    const char *filename = argv[1];

    // Get a string of the full path of the file, using realpath() as the workhorse

    char pathbuffer[MAXPATHLEN];

    char *fullpath = realpath (filename, pathbuffer);

    if (fullpath == NULL) {

        fprintf (stderr, "could not find %s\n", filename);

        return -1;

    }

    NSURL *url = [NSURL fileURLWithPath: @( fullpath )];

    // Ask launch services for the different apps that it thinks could edit this file.

    // This is usually a more useful list than what can view the file.

    LSRolesMask roles = kLSRolesEditor;

    CFArrayRef urls = LSCopyApplicationURLsForURL((__bridge CFURLRef)url, roles);

    NSArray *appUrls = CFBridgingRelease(urls);

    // Extract the app names and sort them for prettiness.

    NSMutableArray *appNames = [NSMutableArray arrayWithCapacity: appUrls.count];

    for (NSURL *url in appUrls) {

        [appNames addObject: url.lastPathComponent];

    }

    [appNames sortUsingSelector: @selector(compare:)];

    // Finally emit to the user.

    for (NSString *appName in appNames) {

        printf ("%s\n", appName.UTF8String);

    }

    return 0;

// main

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

% ./launchHandler launchHandler.m

TextEdit.app

Xcode-4.6.app

Xcode-5.0.2.app

Xcode.app

Xcode6-Beta2.app

% ./launchHandler someGraphic.png

Acorn.app

ColorSync Utility.app

Preview.app

% ./launchHandler ./Flongnozzle-2012

%

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

其他工具

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

翻译:Mr_cyz,于1-19日首发于CocoaChina

时间: 2024-10-27 08:21:57

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

在mac电脑上写入文件到NTFS格式的移动硬盘的解决办法

需求背景: 今天我在Mac电脑A上下载了11G的资料,想传给Mac电脑B,试用了AirPort.文件共享.远程操作等,传输速度都慢得要死,虽然是在同一个局域网下,两台电脑挨的非常的近,但是还是传得超级慢,慢到无法忍受,因此就想我何不用移动硬盘拷贝呢,于是乎找来移动硬盘. 复制资料.向移动硬盘里粘贴,发现无效,粘贴不进去,无法在移动硬盘里创建文件夹.于是google了一番,原来硬盘是NTFS格式的,mac os原生不支持写入权限.继续寻找解决办法,发下如下2篇文章最靠谱: 这2个文章中一个就可以解

Linux查找并删除重复文件的命令行fdupes工具,dupeGuru图形工具

查了几十个网页,找到这个接近满意的解决方案http://unix.stackexchange.com/questions/146197/fdupes-delete-files-aft... 不过正则里面的叹号好像不能起到清除空行的效果,改为d;fdupes --recurse A/ B/ | sed '/^A/d; /^$/d; s/.*/"&"/' | xargs rm 但还有个小问题,如果A里面有重复的文件,但这文件不在B中,fdupes也是会列为结果,导致误删,要再想想

一个新手的Python自学之旅 #MacBook #《“笨办法”学Python》#第三章:言归正传讲Python:Mac系统的终端Terminal命令行快速入门

第三章:言归正传讲Python:Mac系统的终端Terminal命令行快速入门 以后我都会将<“笨办法”学Python>简称为“这本书” 本人用了近5年的MacBook,但在此之前,从未使用过电脑自带的“终端Terminal”(图标:).在非程序员的世界里,建立和删除文件夹或文件,都是:鼠标右键点新建/删除,这是UI带来的便利.但是,却不知道如何利用命令行实现这些操作. 首先,要掌握几个我们平时常用,但在代码界有另外名称的名词:目录.路径.打印. --目录:我们认为它是这样的:标题:第一章:第

一个新手的Python自学之旅 #MacBook #《“笨办法”学Python》#第四章:言归正传讲Python:Mac系统的终端Terminal命令行快速入门之较复杂的命令

第四章:言归正传讲Python:Mac系统的终端Terminal命令行快速入门之"较复杂的命令" 在写第三章的时候,发现自己已经忘记了好多命令.其实我并没有按照Zed A.Shaw的提示,将这些命令做成小卡片,然后每天去记忆.可能源于我的目的并非是为了掌握并精研Python,我写博客并不是单纯为了分享自己的学习经验.而是希望自己能够通过学习python和写博客的形式,让自己以后养成这样的学习和记录习惯,有助于以后技能的掌握和积累.Python起到抛砖引玉的作用. 闲话少说,下面开始介绍

MAC系统XAMPP 中 MySQL命令行客户端配置使用

在PHP的学习过程中,MySQL估计是必然会接触的. MySQL的管理相信大家也会使用phpmyadmin: 好吧,phpmyadmin的确是MySQL管理的神器,你想要的,他好多都有,在开发的过程中,对于后台数据库的设计架构帮助真的很大. 但是,在这篇文章的主角确不是它. MySQL客户端 MySQL安装包里面,在一个名为bin的文件夹,放置了很多工具包,但是使用他们的方式是命令行(ps:最近上瘾了). 在MAC系统,使用命令行的工具可以使用系统自带的Terminal: 顺便在这提一下,笔者使

在Mac电脑上为iPhone或iPad录屏的方法

在以前的Mac和iOS版本下,录制iPhone或者iPad屏幕操作是一件稍微复杂的事情.但是随着Yosemite的出现,在Mac电脑上为iPhone或iPad录屏的方法就变得简单了.下面就介绍一下具体的操作步骤: 操作系统的准备 Mac电脑:需要升级到Yosemite及其以上版本; iPhone或者iPad:需要升级到iOS8及其以上版本; 操作的步骤 1.首先将iPhone设备与Mac电脑连接; 2.打开QuickTime,选择“文件->新建影片录制”;或者快捷键“Option + Comma

mac电脑上的卸载工具?iTrash附注册机的macOS卸载程序

mac电脑上的卸载工具?iTrash是一个macOS卸载程序,点击这里可以安装附带注册机的版本,它使用称为"Levenshtein距离算法"的特殊搜索算法来查找所有相关文件并将其删除.这是因为许多(尽管不是全部)应用程序在整个系统中安装了多个文件和文件夹,这意味着删除应用程序本身并不足以确保您摆脱一切. iTrash Mac特色 1.鬼模式背景模式.将东西放入垃圾桶并弹出iTrash.2.专家模式使用Levenshtein距离搜索算法,它可以追踪更多可能的相关文件.3.简单的拖放将应用

每个 Linux 用户都应该知道的命令行技巧

每个 Linux 用户都应该知道的命令行技巧 原创 2015-09-11 伯乐在线 程序员的那些事 [伯乐在线导读]:有网友在问答网站Quora上提问:“有哪些省时小技巧,是每个Linux用户都应该知道的?” Joshua Levy 平常就在 Linux 平台工作,并且他积累了不少实用命令行技巧,他在回复中精选出一部分.对技术用户来说,这些技巧挺重要或实用,但知道的人并不多.下文略有点长,一般来说,用户也不需要对全部内容都了解,但为了达到省时方便的目的,Joshua Levy 仍不遗余力做了校对

给新手的 10 个有用 Linux 命令行技巧

我记得我第一次使用 Linux 的时候,我还习惯于 Windows 的图形界面,我真的很讨厌 Linux 终端.那时候我觉得命令难以记忆,不能正确使用它们.随着时间推移,我意识到了 Linux 终端的优美.灵活和可用性,说实话,我没有一天不使用它.今天,我很高兴和刚开始接触 Linux 的人一起来分享一些有用的技巧和提示,希望能帮助他们更好的向 Linux 过渡,并帮助他们学到一些新的东西(希望如此). 5 个有趣的 Linux 命令行技巧 这篇文章希望向你展示一些不需要很高的技术就可以像一个高