探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误

在Mac上使用HomeBrew安装telnet时候出现错误,于是,就来探究一番。

执行命令 brew install telnet,错误如下:

探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误_第1张图片

那么 /usr/local/Cellar 这个目录是做什么用的呢? 从Homebrew的官网上面可以看到,Homebrew是先将文件分别安装到独立目录之后,再将其文件软链接至Cellar目录下面。也就是Cellar目录是要放软链接的。

但是从上图中的错误可以看到,错误为Operation not permitted 即在创建 /usr/local/Cellar 目录的时候似乎碰到了权限错误。 那么,接下来我们来验证一下。

既然是最终要放置安装好文件软链接的文件夹出现了问题,那么在使用Homebrew安装其他工具的时候也会出现同样的错误。这里,我再安装下 ruby 试试。

brew install ruby

结果如我们所设想的一样

探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误_第2张图片

看图我们发现,在这个过程中几个组件都碰到了同样的问题。接下来,我们分析下这个权限问题的原因是什么。

首先,我们查看下 /usr/local 这个目录的信息看能不能发现什么。这里,可以使用命令 ls,即

ls -ld /usr/local

其中参数表示

  • -l : 除了文件名以为,还可以将文件的权限、所有者、文件大小等信息详细列出来
  • -d : 即 -directory 将目录像文件一样显示,而不是显示其下的文件

这样可以查看出/usr/local目录本身的信息,结果如下
探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误_第3张图片

这样我们很明显可以看出,所有者是 root, 所数组是wheel。而且只有所属者root具有写的权限,这也就是出现权限问题的原因。顺便说下,这里有个wheel组,这个是用来做什么的呢?引用维基百科上关于Wheel词条的解释如下:

In computing, the term wheel refers to a user account with a wheel bit, a system setting that provides additional special system privileges that empower a user to execute restricted commands that ordinary user accounts cannot access.

Wheel group

Modern Unix systems generally use user groups as a security protocol to control access privileges. The wheel group is a special user group used on some Unix systems to control access to the su or sudo command, which allows a user to masquerade as another user (usually the super user).

解释了有关wheel的来源和wheel group的意思,其实就是一组可以获取特殊权限的用户,具体可以参考 维基百科的wheel词条。

理论上来说,使用sudo来执行root权限肯定可以安装的,但是homebrew是禁止使用sudo进行操作的,因为这个操作太危险了。那要是把 /usr/local目录的所有者改成当前用户呢,这样也就使当前用户执行brew所需要的操作了。很多人解决的办法是 :

sudo chown -R $(whoami) /usr/local/

我现在的系统是 macOS Mojave (10.14.2),执行结果如下:

chown: /usr/local/: Operation not permitted

很明显,最新的系统已经禁止了这种操作。

这让我想起了引起这个问题的起因,就是因为系统对 /usr/local目录增强了安全性。既然是操作系统的改进,那必定是以后的趋势,再改回我觉得并不是个最好的解决办法。突然想到好像在这台电脑上挺久没有用过HomeBrew了,而且这个问题应该是个大部分人都会遇到的问题。作为一个活跃的开源项目,我想这个问题应该早都解决了吧。于是,从brew官网上面找到了卸载的代码 :

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"

顺利卸载,然后重新安装:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

也顺利完成。

再次使用 ls -ld /usr/local/进行查看

image

local目录的权限以及所有人等都没有发生任何变化.

但是,查看 /usr/local/内部的文件可以看到

探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误_第4张图片
其中,我们之前所需要的Cellar目录已经创建完成了,并且其所数组也具有了写的权限。当然,除了Cellar目录,其他所需要的目录页一起创建了,结合安装时候的打印日志,如下:
探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误_第5张图片

这样,在最新的HomeBrew中,安装的时候就将需要的目录都已经创建完成并且分配了所需的权限,那么在用brew去安装其他软件的时候就可以不需要sudo权限直接进行了。我想,应该是没有问题了。

再次安装telnet

brew install telnet

果然,安装成功,没有再提示任何错误。

telnet已经安装在了Cellar目录中。

探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误_第6张图片

总结

最终可以得出,这个问题出现的起因是因为在Mac OS 10.1210.14中将/usr/local的安全性加强引起的,不允许更改所有人等(其中10.1410.12有所加强,可见趋势如此)。最新的HomeBrew安装包通过安装的时候直接创建所需要的目录以及分配足够的权限来解决。

这点我们可以通过下载HomeBrew的安装脚本来证实。很简单,使用curl把安装脚本里面的shell脚本下载到本地

curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install > brew.sh

打开brew.sh,大致看下会发现代码中加入了对10.14版本和10.12的定义
探究 HomeBrew 安装工具是 Cellar目录出现 Errno::EPERM: Operation not permitted @ dir_s_mkdir 错误_第7张图片
这样就可以判断Mac系统在10.1410.12做了比较大的修改,需要专门针对这个脚本作更改。
在安装brew的过程中,需要输入密码来继续,在安装脚本中也很容易看到很多sudo命令的语句,有兴趣可以自己来细看。

建议

如果遇到这个问题,在HomeBrew更新之前我们不得已使用各种奇淫技巧来解决。但是既然现在已经有了更安全更好的解决方案,在遇到相同的问题时我建议直接卸载之前的brew,然后安装最新的。

你可能感兴趣的:(Mac)