在 mac 中打开一个文件会有一个默认的应用. 但是这个应用往往不是我们希望的那个. 比如我想打开一个 .c
, Mac 会启动 XCode来打开这个文件, 这往往不是我希望的.
再比如我想打开一个 .md
文件, 这货居然没有默认打开方式, 这个时候我们可能会右击然后找到那个打开方式, 设置成为 sublime 或者 mou.
但是碰到一个 .markdown
的文件, 系统又蒙圈了, 还是不知道用什么打开, 当然我们也可以按照刚才说的去修改.
那么有没有一个快捷的方式, 可以批量的修改系统中所有文件的默认打开方式呢? 有! 就是我们今天要介绍的 duti
Concepts
duti是 Mac 下的一个命令行工具, 主要作用为不同文件类型设置默认的应用. duti 的意思其实就是 default for UTI
在介绍如何使用之前我们需要明确几个概念:
UTI
Mac 下的文件类型被定义为 Uniform Type Identifiers (UTI). 例如, HTML 文件的 UTI 是 public.html; Word 文档的 UTI 是 com.microsoft.word.doc.
那么改变文件类型的默认打开方式的第一步就是确认文件类型啦.
第一个方式是去看苹果列出来的 UTI Uniform Type Identifiers Reference
第二个方式是使用 mdls
命令, 这哥们的作用就是: lists the metadata attributes for the specified file
那么如何使用呢, 很简单只要把你想要获得 UTI 的文件作为参数就好了
$ mdls test.txt
kMDItemContentType = "public.plain-text"
kMDItemContentTypeTree = (
"public.plain-text",
"public.text",
"public.data",
"public.item",
"public.content"
)
我们可以看到其中就有这样的输出(截取). 可以看到一个 .txt
文件的 UTI 就是 public.plain-text
, 那么下面这一坨是干什么的呢?
因为文件类型也有一个具体和宽泛的划分嘛, 越往下约 general.
再来看一个
$ mdls test.css
kMDItemContentType = "public.css"
kMDItemContentTypeTree = (
"public.css",
"public.text",
"public.data",
"public.item",
"public.content"
)
public.css
就是 .css
的 UTI.
Bundle ID
Bundle ID (应用标识符)) 是 iOS 或者 Mac 应用的唯一标识. 也就是我们希望用什么软件打开我们的文件的那个软件的 ID 啦.
可以用以下命令获得 Bundle ID:
$ osascript -e 'id of app "Finder"'
com.apple.finder
$ osascript -e 'id of app "Atom"'
com.github.atom
$ osascript -e 'id of app "Sublime Text 2"'
com.sublimetext.2
Bundle Id & UTI
那么知道了文件的类型UTI, 知道了软件的 Bundle ID, 距离设定文件的默认程序其实就差一步了.
还有一个概念, 就是这个软件对于这个文件是个什么角色. 其实我们这里大部分情况只需要关心 editor
这个角色. 就是编辑角色. 其他的没啥用.
all: application handles all roles for the given UTI.
viewer: application handles reading and displaying documents with the given UTI.
editor: application can manipulate and save the item. Implies viewer.
shell: application can execute the item.
none: application cannot open the item, but provides an icon for the given UTI.
Usage
好了, 介绍了这么多概念, 终于到了修改文件默认打开方式的时候了!
duti [ -hVv ] [ settings_path ]
如果上述语句没有给settings_path
, duti 将会从标准输入读取配置. 如果setting_path
是个文件夹的话, 那么 duti 将会从文件夹内的所有文件中读取配置.
那么这个 setting_path 文件的每一行其实需要三个字段:
应用的标识符 Bundle ID (比如: com.apple.Safari)
文件类型的 UTI (比如: public.html), 扩展名或者 MIME 类型
应用对于 UTI 的角色是什么 (比如, editor 编辑器)
options
-s: 选项会让 duti 从命令行读参数.
-x ext: 选项会让 duti 输出参数中扩展名对应的默认应用
-d uti: 打印 UTI 的默认应用.
-l uti: 打印 UTI 的所有可用应用.
-V: 打印版本.
-v: 详细输出.
-h: 帮助.
examples
使用 -s 选项, 从命令行读取参数:
duti -s com.apple.Safari public.html all
duti -s com.apple.Finder ftp
但是我比较喜欢把这个设定放到一个文件里, 比如 duti-sublime
,
我希望用 Sublime 打开 .md
, .css
, .js
, 以及富文本文件, 纯文本文件, 以及一些 shell 脚本.
那么我的文件内容如下:
com.sublimetext.2 net.daringfireball.markdown editor
com.sublimetext.2 public.css editor
com.sublimetext.2 public.script editor
com.sublimetext.2 public.source-code editor
com.sublimetext.2 public.rtf editor
com.sublimetext.2 public.plain-text editor
com.sublimetext.2 public.unix-executable editor
运行命令:
duti duti-sublime
然后我们在使用 -x 选项, 打印 UTI 的默认应用
$ duti -x css
Sublime Text 2.app
/opt/homebrew-cask/Caskroom/sublime-text/2.0.2/Sublime Text 2.app
com.sublimetext.2
双击test.css
就是Sublime打开啦~