Mac安装Homebrew并更换国内镜像源
Table of Contents
Mac安装Homebrew并更换国内镜像源
简介与安装
什么是Homebrew?
Homebrew是macOS的包管理工具,相当于Redhat Linux(Centos/RHEL/Fedora)的yum
或者Debian Linux(Debian/Ubuntu)的apt-get
,使用Homebrew能非常方便的下载需要的软件包,比如安装nginx,直接执行以下语句即可安装:
brew install nginx
注意:它虽然叫Homebrew,但实际使用的时候,命令是brew
。
怎样安装Homebrew
安装Homebrew需要先安装“Command Line Tools for Xcode”
xcode-select --install
如果xcode-select --install
提示无法下载,可以手动安装:xcode-select –install 不能安装该软件,因为当前无法从软件更新服务器获得。
然后执行以下命令安装Homebrew:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
另外有国内安装源版本:
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
这个版本安装好之后,它直接就是国内源的,不用再修改成国内源,但是在我后面使用过程中,经常遇到问题,所以还是原始源比较好,国内源也不是说一定会出问题,总之我就遇到过,有其它朋友也遇到过。
Homebrew的一些设计理念
先说一些词:Homebrew、Tap、Formula、Bottles、Cask、Cellar、Pour。
其实Homebrew设计的理念,比较有意思:
- 首先Homebrew的意思是“自酿酒、自酿啤酒”;
- Tap是水龙头(当然水龙头放出来的是酒),其实Tap就是一个软件库,存放软件名对应软件的下载链接;
- Formula在这里是指酒的配方(其实就是软件的下载链接),一个Tap里有很多Formula(就是一个软件库里有很多下载链接);
- Bottles就是酒瓶(瓶装酒,即预先编译好的命令型软件);
- Cask是木桶(桶装酒,应用型软件);
- Cellar就是酒窖(专门放酒的地下室),而Pour是倒酒(装酒)的意思。
一个软件就是一瓶酒(命令型软件,无界面)或一桶酒(应用型软件,一般都有界面),而安装一个软件,就是一个倒(装)酒(Pouring)并把酒瓶子或酒桶放入酒窖的过程
Homebrew安装的命令型软件都会安装到/usr/local/Cellar/
目录下,前面说了,Cellar是酒窖的意思,所以这个目录其实就是用来装酒(瓶装)的酒窖。
而桶装的酒(Cask),则不是放到/usr/local/Cellar/
这个酒窖里的,因为它安装的是一些应用型软件,一般都是有界面的.app
文件,对于这些文件,它会装到“应用程序”目录下。
当然也有可能没有界面,虽然没有界面,但也不是命令版的,比如安装QuickLook插件,虽然插件没有界面,但它本身却是一个macOS的应用,只不过不是传统的.app
格式的应用而已,像这种比较特殊的应用,会安装到它应该安装的地方,这个应该是提交到Homebrew库的时候可以指定安装到哪儿的。
倒(pour)酒(装酒),其实是从水龙头(Taps)里装的,Homebrew官方自带有三个水龙头(Tap)
# 核心Tap(水龙头),这里面的酒是装到酒瓶里的
homebrew/core
# 大水龙头,在这里装酒要用桶来接
homebrew/cask
# 服务水龙头,用于安装可以后台运行的软件的plist文件的(macOS用launchctl管理这些软件,
# Linux的systemctl就是借鉴的macOS的,而plist文件就相当于Linux的".service"文件)
homebrew/services
每个水龙头里都能放出很多不同配方(Formula)的酒,具体放出什么样的酒,需要你来指定配方,比如用brew install nginx
安装nginx,则“nginx”这个关键字就是一个“配方名称”(其实就是软件名称),homebrew会根据这个配方名称,去所有水龙头里找,找到有对应的配方(软件的下载链接)后,就会根据配方看酒厂是否有,如果有就直接从酒厂拿一瓶配方对应的酒(即根据下载链接去下载),如果酒厂没有,那就自己酿造(源码编译),最终放到酒窖(/usr/local/Cellar
)里。从这里能看出来,Homebrew的作者应该是喜欢喝酒或自己酿酒,所以搞了一套这样的概念。
另外,如果官方的水龙头里没有你要的配方的酒(比如你的酒的配方名为“openresty”),你还可以自己添加水龙头brew tap openresty/brew
添加一个名为“openresty/brew”的水龙头,因为这个水龙头里是有你需要的配方“openresty”的,所以添加之后就可以用brew install openresty
来安装“openresty”了(它会自动从你所有的水龙头里找这个配方在哪儿),最终会把一瓶配方名为“openresty”的酒放到酒窖(/usr/local/Cellar/
)里。
另外,它会往/usr/local/bin/
里创建可执行程序的符号链接(软链接),还会往/usr/local/opt/
创建当前版本文件夹的符号链接。
安装文件夹
Homebrew本身安装在哪儿?
Unix/Linux系统,一般第三方软件都是安装到/usr/local/
文件夹中的,Homebrew也不例外,所以Homebrew本身是被安装到了/usr/local/Homebrew/
文件夹下的(这个Homebrew的H的是大写)。
更新:对于M系(如M1/M2等)芯片的Mac,Homebrew会被安装到/opt/homebrew/
中(这个homebrew的h是小写),而使用brew安装的软件,则被安装到/opt/homebrew/Cellar/
中,brew link
的符号链接被创建到/opt/homebrew/bin/
中。
所以对于M系芯片的Mac,你需要把homebrew的bin目录添加到环境变量中
export PATH="/opt/homebrew/bin:$PATH"
关于在M系芯片中的Homebrew方案,具体见:Discussion: longterm Homebrew prefix on Apple Silicon Macs #9177。
Homebrew把软件安装到哪儿了?
命令软件会被安装到/usr/local/Cellar/
文件夹下(M系芯片的Mac下,命令软件会被安装到/opt/homebrew/Cellar/
)。
以redis为例,如下图,它被安装到了/usr/local/Cellar/redis/
目录下,并且在该目录下还有一个以版本号命名的目录,进入到版本号命名目录中,才是真正的redis安装目录,这样做的原因是,一个软件有可能安装多个版本
如果安装时要使用--cask
参数,说明这种软件是非命令软件而是有界面的软件,这种软件是直接安装到了系统的“应用程序”文件夹的,也就是/Applications/
文件夹。
Homebrew如何把命令添加到环境变量中?
我们知道,命令软件都需要添加到环境变量中才能直接在终端中使用,否则每次使用你都得进入它所在的文件夹,这样会非常麻烦。
所以Homebrew会在/usr/local/bin/
目录下创建一个该软件的符号链接(即软链接)来链接到它真正的目录,还是以redis为例,如下图,所有redis的命令都被软链到/usr/local/bin/
了,而由于/usr/local/bin/
目录本来就在环境变量中,这样就相当于所有这些redis的命令都加入到了环境变量中了
注意:对于M系芯片的Mac,符号链接会被创建到/opt/homebrew/bin/
中,所以你必须把该路径添加到环境变量中
export PATH="/opt/homebrew/bin:$PATH"
另外两个软链接目录
brew除了往/usr/local/bin/
中创建软链接,还会往以下两个目录中创建软链接
/usr/local/opt/
/usr/local/lib/
往/usr/local/opt/
创建的软链接,是该软件的版本文件夹软链接,还是以redis为例,它会创建一个当前最新版本的目录的软链,直接就叫redis
,不带版本号
/usr/local/opt/redis/ -> /usr/local/Cellar/redis/6.2.2/
另外它还会为每个版本文件夹都创建一个软链接,包括最新的版本(当然因为我这里只有一个版本,所以它就只有一个)
/usr/local/opt/[email protected]/ -> /usr/local/Cellar/redis/6.2.2/
另外它还会为软件的动态链接库创建一个软链接到/usr/local/lib/
目录下,方便其它依赖它的软件能调用它的动态链接库
创建软链接的原因,都是为了避免直接把路径指向Cellar目录,因为Cellar目录中的软件都是带版本号的,如果直接指向Cellar目录,这代表每次更新软件版本,依赖它的动态链接库的另一个软件都要重新编译重新指定路径,非常麻烦。
具体原因可参见:这个回答。
什么是keg-only?
keg是小桶的意思,与此对应,cask是比较大的桶。keg-only英文本义是“只有桶、只在桶里”,其实就是因为brew命令检测到/usr/local/bin/
中已经存在该命令,如果再创建软链接就会覆盖,所以它就不创建,让这个软件“只在桶里”,而不与外界发生联系,你需要自己处理这种情况,比如原有的那个命令是不是你自己手动安装的?如果能删掉的就删掉,然后用brew link xxx
来创建链接。
更换国内源
由于众所周知的原因,Homebrew安装软件非常慢,所以我们要把它的安装源更换成国内的源,这样才能用它愉快的安装软件。
后记:事实证明切换到国内源并不一定能愉快的安装软件,时不时出问题的,所以我后来还是没有切换国内源,直接走代理。
要更换的源有三个:Homebrew本身的源、Tap(Formula)源以及Bottles源。
更换Homebrew本身的源
Homebrew本身就是一个软件,是用ruby语言编写的,它的代码存放在github,当执行brew update时就会从github更新代码(如果一段时间没更新了,用brew安装软件也会先执行update),所以如果这个源没有修改为国内源,它默认是在github上的(homebrew),速度会比较慢,所以我们更换它的源,先进入Homebrew安装目录:
#其实这个目录就是:/usr/local/Homebrew/
cd "$(brew --repo)"
然后修改git源为中科大的源:
git remote set-url origin git://mirrors.ustc.edu.cn/brew.git
以上两条命令也可以合并一起执行:
cd "$(brew --repo)" && git remote set-url origin git://mirrors.ustc.edu.cn/brew.git
修改后,可以使用以下使用查看刚刚的修改:
git remote get-url origin
当然也可以直接在配置文件里看:
vim .git/config
因为是修改git源,其实就是修改remote-url,其实就是修改当前目录下的.git/config
文件里的配置,注意.git
目录是隐藏目录,要用ls -la
才能看到
如果你要换回去,也是完全一样的命令,只不过地址不同而已,换回去的地址为(当然也可以手动去编辑配置文件.git/config
来换链接)
cd "$(brew --repo)" && git remote set-url origin https://github.com/Homebrew/brew.git
更换Tap(Formula)的源
前面说过,Tap就是水龙头,Formula是酒的配方的意思(其实一个配方就是一个软件名字及其对应的下载链接),同一个水龙头(Tap)下的所有配方(Formula)来源都是一样的(事实上,一个Tap就是一个Formula库,里面包含很多Formula,即软件的下载链接),我们可以执行brew tap
来查看当前有哪些水龙头,当然你可以直接到/usr/local/Homebrew/Library/Taps/
目录下查看,其中homebrew里的三个就是官方的水龙头(Tap),而其它名字的,就是自己用brew tap xxx
的方法添加的。
这是我电脑里的Formula,除了三个官方的,其它都是自己添加的
exolnet/deprecated
homebrew/cask
homebrew/core
homebrew/services
minio/stable
openresty/brew
比如我想通过brew安装openresty,但是homebrew-core(就是官方的库)中并没有,所以我就去网上搜索,结果发现这个,它里面有告诉你怎么添加这个
# 添加一个名叫“openresty/brew”的水龙头(Formula库,事实上这个库里只有一个配方,那就是openresty)
brew tap openresty/brew
# 删除一个叫“openresty/brew”的水龙头
brew untap openresty/brew
事实上官方的三个水龙头(Tap):homebrew/core、homebrew/cask、homebrew/services都是在github上的,另外第三方的Tap其实也都是在github上发布代码的,所以这些水龙头(Tap)里面的配方(Formula)也都是在github上的。
当安装一个软件时,它会在所有的水龙头(Tap)里找你指定的配方(Formula),找到这个配方后(软件的下载地址),再根据这个配方去酒厂拿一瓶(即根据下载链接去下载),如果酒厂没有就自己酿酒(源码编译),因为Formula库在github,而且也比较多,所以会比较慢,所以我们需要把它更新为国内源(比较快的是中科大的,清华大学也有,听说没中科大的快)。
由于官方的Tap有三个,所以我们要分别修改这三个官方Tap,而自己添加的Tap是没有国内源的,因为没有人知道你会添加什么Tap,自然就无法做国内源,而且非官方的东西一般也没人会去做。
下面这些命令是替换三个默认的官方的Tap源
# 把homebrew-core源切换为中科大源
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git
# 把homebrew-core源恢复到原本的github源
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://github.com/Homebrew/homebrew-core.git
# 把homebrew-cask源切换为中科大源
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-cask"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-cask.git
# 把homebrew-cask源恢复到原本的github源
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-cask"
git remote set-url origin https://github.com/Homebrew/homebrew-cask.git
# 把homebrew-cask-versions源切换为中科大源
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-cask-versions"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-cask-versions.git
# 把homebrew-cask-versions源恢复到原本的github源
cd "$(brew --repo)"/Library/Taps/homebrew/homebrew-cask-versions
git remote set-url origin https://github.com/Homebrew/homebrew-cask-versions.git
其中homebrew-cask-versions默认是没有的,它相当于是cask这个Tap的扩展,能提供更多的版本,比如beta版,如果你想用它,需要brew tap homebrew/cask-versions
添加,添加之后再来替换它的源为国内源。
更换Bottles源
前面说过,一个软件其实就是一瓶(或一桶)酒,当Homebrew根据你提供的配方名称(Formula)查找到配方(软件下载链接)后,就会根据这个配方去酒厂拿酒(如果酒厂没有就自己酿,即编译),而酒厂在哪儿呢?在bintray,也就是说,brew下载软件是去bintray里下载的,这个网站也是国外的,不用科学上网几乎都打不开,所以慢是肯定的,所以我们要把它替换成国酒厂(国内源),会比较快。
这里还是用中科大的,不过由于Bottles源不在gittub,所以这里就不是替换github的remote-url了,而是在环境变量里设置一个HOMEBREW_BOTTLE_DOMAIN
环境变量:
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles' >> ~/.bash_profile
source一下让它生效:
source ~/.bash_profile
注意:如果你更换了其他的shell,比如zsh,请自己更换名称即可,zsh的要这样添加(其实你自己用vim打开.zshrc添加也是一样的):
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles' >> ~/.zshrc
source一下让它生效:
source ~/.zshrc
如果要用回原来的,直接把添加的那句删掉,再source ~/.bash_profile
或source ~/.zshrc
即可(此时必须开一个新终端窗口)。
好了,到这里,三个源都更换完毕,赶紧试试你的Homebrew有没有飞起来吧。
防止自动更新
brew默认安装软件时,会自动更新其它软件,可以通过以下环境变量来设置是否自动更新
# 取消自动更新
export HOMEBREW_NO_AUTO_UPDATE=1
# 取消自动清理
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew的基本使用
使用命令
查询软件:
brew search 软件名
安装软件:
brew install 软件名
对于需要在后台运行的软件,大部分可用以下方式启动|停止|重启(它的原理是用launchctl+plist,用这种方式启动的软件重启电脑后也会自动启动):
brew services start|stop|restart 软件名
关于brew services的原理及详细用法,请查看:Mac服务管理 – launchd、launchctl、LaunchAgent、LaunchDaemon、brew services详解。
更新软件:
brew upgrade 软件名
注意不要用update,用update是更新brew自己,但brew每次安装软件时都会先更新自己,所以不需要手动去更新自己。
另外,使用upgrade更新一个软件,有可能“牵一发而动全身”,什么意思呢?比如我更新的一个软件A是用python写的,当我更新它的时候,如果它的新版本依赖的python版本比较高,那么它会自动更新python,而python被更新后,另外两个也是python写的软件又因为python更新了,它们的版本也需要更新,最终看起来就是,你明明只想更新软件A,但最终却连带更新了B、C、D、……。
卸载软件:
brew uninstall 软件名
查看软件的信息:
brew info 软件名
查看安装了哪些软件:
brew list
查看某个软件安装到哪儿去了:
brew list 软件名
查看帮助:
brew help
查看所有包的依赖树
brew deps --installed --tree | less
查看ffmpeg依赖于哪些包
brew deps ffmpeg
在默认浏览器中打开homebrew主页
brew home
清除老版本
# 清除所有软件的老版本
brew cleanup
# 只清除git的老版本
brew cleanup git
查看哪些软件已过期(已过期说明有更新的版本可以更新)
brew outdated
使用客户端软件Cakebrew
其实最初是只有命令的,只是后来可能有人觉得用命令麻烦,就开发了Cakebrew:
但据使用的人反馈,这个软件还是有些问题的,没有直接用命令那么好。
还有为什么三个源都换了之后还是找不到hadoop这个软件呢…
这个软件找不到,可能是它没放在brew库里,或者你需要自己tap添加源,可以网上找找为什么,因为国内源是镜像原始的国外源,并不是增加,所以如果原始的源没有,那么换国内源一样没有的。
另外问一下,刚
No such remote ‘origin’
这个错误,是换https就解决了吗?我在网上搜了一下,说要增加远程的URL,于是添加了 git remote add origin “xxx.git”的命令,再执行那两条换formula源的语句就好了。我没有执行三次换源语句之前是能找到hadoop的,但是在安装到60%的地方就失败了,而且速度特别慢。换源之后就死活找不到,换回原来的源也找不到。于是我删了homebrew重装了一次,也没换源,直接安装,结果这次畅通无阻,速度也很快。但奇怪的是我没有在命令行里执行换源语句,显示的下载路径也是Downloading https://mirrors.ustc.edu.cn/homebrew-bottles/bottles/openjdk-13.
不管如何,安装好了就行哈哈哈。谢谢您的及时回复!
好的,我最开始换源感觉没啥问题,后来也是感觉有些下载不了,又换回去了,然后直接开代理解决。
看你这里下的是中科大的bottles源,说明你重装homebrew并没有重置之前的换源修改,因为bottles源是在
~/.bashrc
里设置的,所以才会造成你重新homebrew还是会下中科大源的原因,因为重装homebrew只会重置homebrew本身的源以及它的formula源。您好!请问在换formula源的时候,出现No such remote ‘origin’是怎么回事呢?
是这句
git remote set-url origin git://mirrors.ustc.edu.cn/homebrew-core.git
报的错吗?把git://
换成https://
试试看?我也是猜的,没试。文章挺好的,给了我不少的帮助,谢谢。
不过换回Homebrew源的command缺少origin,正确的应该是:
cd “$(brew –repo)” && git remote set-url origin https://github.com/Homebrew/brew.git
很高兴我的文章能帮到你,也感谢你的提醒,已修改!