解决macOS上不明程序不被允许打开

发布于 2020-05-03 12:43:09

macOS 系统在 OS X Mountain Lion 版本之后提供了 GateKeeper 程序来对应用程序做审核,未通过的将不被允许运行。

手动解决方案是在 Finder 里定位到此程序文件,在菜单里点击“打开”,才会在对话框多出一个“打开”的按钮选项。

但通过终端命令行执行此操作将快速很多。

How to manage OS X Gatekeeper from the command line 这篇文章讲了如何使用 spctl 命令来达到这个目的

# enable/disable gatekeeper
spctl --master-enable
spctl --master-disable

# determine if an application is allowed
spctl -a /Path/To/program.app

# add rule to allow an application
spctl --add --label "MyLabel" /Path/To/program
spctl --enable --label "MyLabel"
spctl --disable --label "MyLabel"

# listing and deleting rules
spctl --list
spctl --list --label "MyLabel"
spctl --remove --label "MyLabel"

通过如下示范可以看出可以为任意文件添加规则以跳过 GateKeeper 的检查,并且可以为规则添加自定义的 label 方便管理。

$ sudo spctl --add --label 'weaming' $DL/1.pdf
$ sudo spctl --list --label 'weaming'
5422[weaming] P0 allow execute [/Users/garden/Downloads/1.pdf]
	cdhash H"69f320e1acd7dcdac72f4f8a260f669e9cd34e36"
$ md5 $DL/1.pdf
MD5 (/Users/garden/Downloads/1.pdf) = df57ce14ed0125688a4c807d4c91a1ef
$ sudo spctl --add --label 'weaming' $DL/2.pdf
$ sudo spctl --list --label 'weaming'
5423[weaming] P0 allow execute [/Users/garden/Downloads/2.pdf]
	cdhash H"9b9bb77cf482bb2e0bccb10957fe21bd3f794135"
5422[weaming] P0 allow execute [/Users/garden/Downloads/1.pdf]
	cdhash H"69f320e1acd7dcdac72f4f8a260f669e9cd34e36"
$ sudo spctl --remove --label 'weaming'
$ sudo spctl --list --label 'weaming'
error: no matches for search or update operation

最后可以通过一个 fish 函数封装来方便地执行此操作

function add-rule-to-allow-executable
    sudo spctl --add --label "$USER" $argv[1]
    sudo spctl --list --label "$USER"
end

戏剧性翻转

执行完上述 sudo spctl --add 过程之后,发现依然不能打开。

当然全局禁用掉 GateKeeper 也是可以的,但是添加的规则没有达到想要的效果。

搜索到 How to allow install of non app store or identified developers on MacOS Sierra 才发现正确的做法是通过 xattr -c 命令删除掉文件的「扩展属性」(extended attributes)。

通过 man xattr 可以看到它的用法:

NAME
     xattr -- display and manipulate extended attributes

SYNOPSIS
     xattr [-lrsvx] file ...
     xattr -p [-lrsvx] attr_name file ...
     xattr -w [-rsx] attr_name attr_value file ...
     xattr -d [-rsv] attr_name file ...
     xattr -c [-rsv] file ...
     xattr -h | --help

DESCRIPTION
     The xattr command can be used to display, modify or remove the extended attributes of one or more
     files, including directories and symbolic links.  Extended attributes are arbitrary metadata stored
     with a file, but separate from the filesystem attributes (such as modification time or file size).
     The metadata is often a null-terminated UTF-8 string, but can also be arbitrary binary data.

     One or more files may be specified on the command line.  For the first two forms of the command, when
     there are more than one file, the file name is displayed along with the actual results.  When only one
     file is specified, the display of the file name is usually suppressed (unless the -v option described
     below, is also specified).

     In the first form of the command (without any other mode option specified), the names of all extended
     attributes are listed.  Attribute names can also be displayed using ``ls -l@''.

     In the second form, using the -p option (``print''), the value associated with the given attribute
     name is displayed.  Attribute values are usually displayed as strings.  However, if nils are detected
     in the data, the value is displayed in a hexadecimal representation.

     The third form, with the -w option (``write''), causes the given attribute name to be assigned the
     given value.

     The fourth form, with the -d option (``delete''), causes the given attribute name (and associated
     value), to be removed.

     In the fifth form, with the -c option (``clear''), causes all attributes (including their associated
     values), to be removed.

     Finally, the last form, with either the -h or --help option, displays a short help message and exits
     immediately.

OPTIONS
     -l  By default, the first two command forms either displays just the attribute names or values,
         respectively.  The -l option causes both the attribute names and corresponding values to be dis-
         played.  For hexadecimal display of values, the output is preceeded with the hexadecimal offset
         values and followed by ASCII display, enclosed by ``|''.

     -r  If a file argument is a directory, act as if the entire contents of the directory recursively were
         also specified (so that every file in the directory tree is acted upon).

     -s  If a file argument is a symbolic link, act on the symbolic link itself, rather than the file that
         the symbolic link points at.

     -v  Force the file name to be displayed, even for a single file.

     -x  Force the attribute value to be displayed in the hexadecimal representation.

         The -w option normally assumes the input attribute value is a string.  Specifying the -x option
         causes xattr to expect the input in hexadecimal (whitespace is ignored).  The xxd(1) command can
         be used to create hexadecimal representations from exising binary data, to pass to xattr.

探究下文件的扩展属性:

# 列出所有的扩展属性
$ ls -l@ $PWD/tools/clients/v2ray
-r-xr-xr-x@ 1 garden  staff  17893800 Jan  1  2010 /Users/garden/Downloads/stairspeedtest_reborn_darwin64/tools/clients/v2ray
	com.apple.quarantine	      19

# 查看 com.apple.quarantine 属性
$ xattr -p com.apple.quarantine $PWD/tools/clients/v2ray
0082;5eae5913;Keka;

关于 com.apple.quarantine 的详情,参见 Launch Services Release Notes

对应解决办法是

sudo xattr -c com.apple.quarantine <file>
# or
sudo xattr -cr <directory>

# 或者仅仅删掉 com.apple.quarantine 属性
sudo xattr -c com.apple.quarantine <file>