作为Linux的忠实爱好者,真的是无法容忍一款没有命令行包管理工具的类unix操作系统,比如说Mac,但又割舍不下对苹果本子的喜爱,于是我决定使用第三方软件填补Mac在这一方面的缺失,搜索一番之后发现原来早就有此类开发项目存在,所以说生活在当下真是幸福,Mac平台下的第三方包管理工具主要有三款:Fink,Macports和HomeBrew,我自然不会放弃试用上面任何一款包管理工具,之前也提及过任何一款包管理工具提供的功能以及实现功能的机制都是类似的:
Mechanism: get resource from Remote source repository & provide dependency management of packages
Function: 1. search packages from remote side; 2. download/install/upgrade packages from remote side; 3. list packages installed and files of special package; 4. uninstall packages
上面是对包管理工具的essential function简要概括,下面分别安装三款工具作对比。
HomeBrew
HomeBrew使用ruby脚本作为安装程序,可见https://brew.sh
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
上述命令的意思是调用ruby解释器执行网址指定的install脚本,和直接用浏览器将网址定义的文件下载到本地然后ruby
相同的效果。
在terminal中敲入上述命令,在选项出敲击回车即可,部分回显信息摘录如下。
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following existing directories will be made group writable:
/usr/local/bin
==> The following existing directories will have their owner set to ftericsson:
/usr/local/bin
==> The following existing directories will have their group set to admin:
/usr/local/bin
==> The following new directories will be created:
/usr/local/Cellar
/usr/local/Homebrew
/usr/local/Frameworks
/usr/local/etc
/usr/local/include
/usr/local/lib
/usr/local/opt
/usr/local/sbin
/usr/local/share
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
/usr/local/varPress RETURN to continue or any other key to abort
可见HomeBrew默认安装路径是/usr/local/
,brew命令在/usr/local/bin/brew
,该命令为shell脚本。在HomeBrew的世界里formula的概念很重要,每个软件包都有对应的formula文件,文件为ruby脚本,大体描述了软件包的用处,下载地址,需要直接从homebrew bottle下载包(bottle do)还是从脚本定义的URL下载包,然后就是安装软件所需要的操作,包括compile,建立softlink和文件移动等。
localhost:Formula ftericsson$ cat /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/zzz.rb
class Zzz end
例如说上面这个包就不使用bottle repo,而是直接从URL定义的地址下载源码包,然后在本地安装。
localhost:Formula ftericsson$ cat libpano.rb
class Libpano :sierrasha256 "a4920c760a4aff60251d8876499ae14eeb52dd4f17adc5a19d14d2f79959590d" => :el_capitansha256 "9188bc29e6e0b271cea0e3b017c0f222825d49bf67d1f65f2a2ecbde6bf870ea" => :yosemitesha256 "cfba56608e1be4c285ad75dd67299405384b690b8cad0d397859a4e29f7f2e9c" => :mavericksenddepends_on "libpng"depends_on "jpeg"depends_on "libtiff"def installsystem "./configure", "--disable-dependency-tracking","--prefix=#{prefix}","--mandir=#{man}"system "make", "install"end
end
而对于这个包就使用bottle repo地址下载然后安装。
brew command usage:
brew help; brew help
brew config
brew search(list all package in remote side); brew search
brew install
brew info
brew list
brew update
使用brew config
命令可以看到以下回显信息
localhost:bin ftericsson$ brew config
HOMEBREW_VERSION: 1.1.11
ORIGIN: https://github.com/Homebrew/brew
HEAD: 394f9fa0aaa5854aa52bc589708a079665dcf462
Last commit: 3 weeks ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 99463de1bf4c31e360915768148b1ada4ae3ae9c
Core tap last commit: 28 minutes ago
HOMEBREW_PREFIX: /usr/local
HOMEBREW_REPOSITORY: /usr/local/Homebrew
HOMEBREW_CELLAR: /usr/local/Cellar
HOMEBREW_BOTTLE_DOMAIN: https://homebrew.bintray.com
CPU: quad-core 64-bit haswell
Homebrew Ruby: 2.0.0-p648
Clang: 8.0 build 800
Git: 2.10.1 => /Applications/Xcode.app/Contents/Developer/usr/bin/git
Perl: /usr/bin/perl
Python: /usr/bin/python
Ruby: /usr/bin/ruby => /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby
Java: 1.8.0_121
macOS: 10.12.3-x86_64
Xcode: 8.2.1
CLT: N/A
X11: N/A
通过上面的配置信息可以看出HomeBrew的软件架构:
1.使用HOMEBREW_PREFIX
变量为安装程序定义根目录,然后在该root目录下建立bin, lib, etc
等Unix类系统常用文件夹以便于为安装程序建立softlink调用,默认是/usr/local
。
2.使用HOMEBREW_REPOSITORY
变量定义HomeBrew程序根路径,HomeBrew程序托管在GitHub上,因此程序也以git.repo的形式存储在本地定义的根目录下,这样既方便程序的更新也可防止程序被修改后没法恢复的风险,默认情况下HomeBrew程序包含两个repo,分别是brew.git
和homebrew-core.git
,brew.git repo的路径为$HOMEBREW_REPOSITORY
,默认就是/usr/local/Homebrew
。
localhost:Homebrew ftericsson$ pwd
/usr/local/Homebrew
localhost:Homebrew ftericsson$ git remote -v
origin https://github.com/Homebrew/brew (fetch)
origin https://github.com/Homebrew/brew (push)
homebred-core.git repo的路径为$HOMEBREW_REPOSITORY/Library/Taps/homebrew/homebrew-core
,默认是/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core
。
localhost:homebrew-core ftericsson$ pwd
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core
localhost:homebrew-core ftericsson$ git remote -v
origin https://github.com/Homebrew/homebrew-core (fetch)
origin https://github.com/Homebrew/homebrew-core (push)
3.使用HOMEBREW_CELLAR
变量定义程序下载后在本地的存放路径,也即程序真实的安装路径,默认是/usr/local/Cellar
,一般会通过在/usr/local/bin
文件夹下建立softlink的方式实现终端调用执行。
4.使用HOMEBREW_BOTTLE_DOMAIN
变量指定Homebrew Bottles源,默认是官方的源 https://homebrew.bintray.com
因此我们可以在不改变本地HomeBrew文件架构的情况下更换git和软件源以实现快速更新。
更换和重置git源参考 https://lug.ustc.edu.cn/wiki/mirrors/help/brew.git
cd $HOMEBREW_REPOSITORY
git remote set-url origin https://mirrors.ustc.edu.cn/brew.git
#git remote set-url origin https://github.com/Homebrew/brew.git
cd $HOMEBREW_REPOSITORY/Library/Taps/homebrew/homebrew-core
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git
#git remote set-url origin https://github.com/Homebrew/homebrew-core.git
更换和重置软件源参考 https://lug.ustc.edu.cn/wiki/mirrors/help/homebrew-bottles
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles' >> ~/.bash_profile
source ~/.bash_profile
HomeBrew卸载
官方方案ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
传统方案参考 https://superuser.com/questions/203707/how-to-uninstall-homebrew-mac-os-x-package-manager
cd `brew --prefix`
git checkout master
git ls-files -z | pbcopy
rm -rf Cellar
bin/brew prune
pbpaste | xargs -0 rm
rm -r Library/Homebrew Library/Aliases Library/Formula Library/Contributions
test -d Library/LinkedKegs && rm -r Library/LinkedKegs
rmdir -p bin Library share/man/man1 2> /dev/null
rm -rf .git
rm -rf ~/Library/Caches/Homebrew
rm -rf ~/Library/Logs/Homebrew
rm -rf /Library/Caches/Homebrew
Command Line Tools
The bottle needs the Apple Command Line Tools to be installed.
You can install them, if desired, with xcode-select --install
.
HomeBrew架构深层次探究
通过观察研究将HomeBrew的基本架构归纳如上图所示:
HomeBrew不仅紧密依托ruby脚本来构建软件包的formula文件,更是依托GitHub构建出灵活扩展的repository架构,每个repository都可通过git clone命令部署到本地,且路径格式保持一致均是
,且git repo均以homebrew-
开头,在repo下构建Formulas文件夹,该文件夹下是以软件包命名的ruby脚本。
Repo的索引格式是
,对应GitHub链接是https://github.com/
,该repo下包的索引格式是
,repo本地路径则是/usr/local/Homebrew/Library/Taps/
Repo可分为官方和第三方两种类型,official repo的git user是homebrew,目前第三方的repo就是所谓的HomeBrew-cask,该repo的git user是caskroom。
official repo:https://github.com/Homebrew
Homebrew cask repo: https://github.com/caskroom
其中官方的homebrew-core repo是随着homebrew安装默认部署(tap)到本地的,想要部署其他的官方和非官方的repo需要使用brew tap
命令。 http://docs.brew.sh/brew-tap.html
brew tap adds more repositories to the list of formulae that brew tracks, updates, and installs from. By default, tap assumes that the repositories come from GitHub, but the command isn’t limited to any one location.
brew tap
brew tap
Example:
localhost:homebrew-cask ftericsson$ brew tap caskroom/homebrew-fonts
==> Tapping caskroom/fonts
Cloning into '/usr/local/Homebrew/Library/Taps/caskroom/homebrew-fonts'...
remote: Counting objects: 1121, done.
remote: Compressing objects: 100% (648/648), done.
remote: Total 1121 (delta 756), reused 538 (delta 470), pack-reused 0
Receiving objects: 100% (1121/1121), 206.66 KiB | 41.00 KiB/s, done.
Resolving deltas: 100% (756/756), done.
Tapped 0 formulae (1,137 files, 925.4KB)localhost:homebrew-cask ftericsson$ brew tap
caskroom/cask
caskroom/fonts
homebrew/core
从这里也可以看出每个tap的repository都是一个软件索引源,homebrew-core是官方的索引源,homebrew-cask是第三方索引源。
HomeBrew-Cask https://caskroom.github.io
Homebrew Cask extends Homebrew and brings its elegance, simplicity, and speed to macOS applications and large binaries alike.
homebrew-cask基于homebrew的拓展命令构建,It’s implemented as a homebrew external command called cask,参考http://docs.brew.sh/External-Commands.html
External commands come in two flavors: Ruby commands and shell scripts.
In both cases, the command file should be executable (chmod +x) and live somewhere in PATH.
因此如果基于homebrew(official repo)使用brew,正常使用brew命令即可,软件会安装到/usr/local/Cellar路径下。如果基于caskroom(third-party repo)使用brew,在brew命令之后添加一个cask
参数即可,程序安装到/usr/local/Caskroom路径下。
localhost:~ ftericsson$ brew cask search google-chrome
==> Exact match
google-chrome
localhost:~ ftericsson$ brew cask install google-chrome
==> Satisfying dependencies
complete
==> Downloading https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg
######################################################################## 100.0%
==> No checksum defined for Cask google-chrome, skipping verification
==> Moving App 'Google Chrome.app' to '/Applications/Google Chrome.app'google-chrome was successfully installed!
localhost:~ ftericsson$ brew cask list
google-chrome
localhost:~ ftericsson$ brew cask info google-chrome
google-chrome: latest
https://www.google.com/chrome/
/usr/local/Caskroom/google-chrome/latest (57KB)
From: https://github.com/caskroom/homebrew-cask/blob/master/Casks/google-chrome.rb
==> Name
Google Chrome
==> Artifacts
Google Chrome.app (app)
localhost:~ ftericsson$ brew cask uninstall google-chrome
==> Removing App: '/Applications/Google Chrome.app'