前言
此篇博文是笔者所总结的 Macos 系列之一;
本文为作者的原创作品,转载需注明出处;
安装
High Sierra 之前的版本
将 /usr/local 的 ownership 设置为当前用户
1
$ sudo chown -R `whoami` /usr/local
`whoami`输出的既是当前的用户名;设置的原因是,brew 的安装文件存放在 /user/local 目录下的,所以需要该目录的权限;
- install Homebrew
1
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
High Sierra 之后的版本
在 High Sierra 中不允许更爱 /usr/local 的所有权利了,所以上述 #1 失效;不过好消息是,Homebrew 的安装脚本也更新了,只需要执行下面这一步操作,1
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
输出,1
2
3
4
5
6
7
8
9
10
11......
Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/mkdir -p /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
Password:
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
==> /usr/bin/sudo /bin/chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions
==> /usr/bin/sudo /usr/sbin/chown shangyang /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/bin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/local/Caskroom /usr/local/Homebrew /usr/local/Frameworks
==> /usr/bin/sudo /bin/mkdir -p /Users/shangyang/Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Users/shangyang/Library/Caches/Homebrew
......
可以看到,安装过程中,会自动的给相关的文件夹赋予权限;
常用命令
brew isntall
比如,我要安装 php,直接,1
brew install php
但是这样安装的弊端是,永远都是安装最新版本的;如果要安装指定版本,参考 brew search 章节;并且,相关安装后的信息,比如包路径通常是放在 /usr/local/Cellar 中的,可执行文件通常是放在 /usr/local/opt/<name>/bin 中的,这部分的详细介绍内容,同样参考 brew search 中的内容;
brew list
1 | $ brew list |
它会显示你本地通过 brew 已安装的所有应用;
brew reinstall
brew reinstall 通常是用来修复某个已损坏的安装包的,注意,它的修复方式是用最新版本来覆盖更新;以我本地的 php 为例,
本地的 php 7.2.3 报错,
1
2
3
4
5$ php -v
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.60.dylib
Referenced from: /usr/local/bin/php
Reason: image not found
Abort trap: 6这个时候,可以尝试通过 reinstall 的方式进行修复,
1
$ brew reinstall php
检查,
版本号,1
2
3
4
5$ php -v
PHP 7.2.5 (cli) (built: Apr 26 2018 12:07:32) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.5, Copyright (c) 1999-2018, by Zend Technologiesinfo,可见,当前被激活的是 7.2.5,并且老版本 7.2.3 已经消失了;
1
2
3
4
5
6
7
8$ brew info php
php: stable 7.2.5 (bottled)
General-purpose scripting language
https://secure.php.net/
/usr/local/Cellar/php/7.2.5 (515 files, 79.1MB) *
Poured from bottle on 2018-05-10 at 09:12:07
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/php.rb
==> Dependencies查看本地安装包路径的内容,
1
2$ ls /usr/local/Cellar/php
7.2.5可以看到,已经完全覆盖了了 7.2.3 包;所以,如果要保持原有版本不变,那么需要指定安装包的版本;但是依然要注意的是,使用这个命令以后,其它不同版本的安装包会被自动删除;
brew uninstall
1 | brew uninstall jenkins |
等价于执行 brew remove
brew info - 检查已安装包信息
检测本地是否安装过该软件,并且提示当前的最新稳定版本的信息;
如果某个软件已经安装,那么会显示已安装的信息
下面,以检查 postgresql 为例,1
2
3
4
5
6
7
8
9
10$ brew info postgresql
postgresql: stable 9.3.2 (bottled)
http://www.postgresql.org/
Conflicts with: postgres-xc
/usr/local/Cellar/postgresql/9.1.5 (2755 files, 37M)
Built from source
/usr/local/Cellar/postgresql/9.3.2 (2924 files, 39M) *
Poured from bottle
From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/postgresql.rb
# … and some more可以看到,它会显示本地已安装包的信息,包括安装的路径等等;
如果某个软件未安装,那么会显示该软件的最新安装包信息,并且显示 Not installed
下面,以检查 mesos 的安装包的信息为例进行演示,1
2
3
4
5
6
7
8
9
10
11$ brew info mesos
mesos: stable 1.3.0 (bottled)
Apache cluster manager
https://mesos.apache.org
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/mesos.rb
==> Dependencies
Build: apr-util ✘, maven ✘
Required: subversion ✘
==> Requirements
Required: java >= 1.7 ✔, macOS >= 10.8 ✔上面会显示
Not installed
以及相关的其它依赖的信息;
brew search - 安装指定版本软件
当我们需要安装某个特定版本的安装包的时候,该如何操作呢?下面以安装 mongodb 特定版本 3.4.6 为例进行描述,
首先,通过 brew search 检索可用的安装包信息
1
2
3
4
5
6
7$ brew search mongodb
==> Formulae
mongodb mongodb@3.0 mongodb@3.2 mongodb@3.4 mongodb@3.6 percona-server-mongodb
==> Casks
homebrew/cask-versions/mongodb-compass-beta homebrew/cask/mongodb-compass homebrew/cask/mongodb-compass-isolated-edition homebrew/cask/nosqlbooster-for-mongodb
homebrew/cask/mongodb homebrew/cask/mongodb-compass-community homebrew/cask/mongodb-compass-readonly homebrew/cask/orelord-mongodb可见,当前总共有 4 个版本可以安装;
然后,安装指定版本即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42$ brew install mongodb@3.4
Updating Homebrew...
==> Installing dependencies for mongodb@3.4: openssl
==> Installing mongodb@3.4 dependency: openssl
==> Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2p.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring openssl-1.0.2p.high_sierra.bottle.tar.gz
......
==> Summary
🍺 /usr/local/Cellar/mongodb@3.4/3.4.17: 19 files, 285.6MB
==> Caveats
==> openssl
A CA file has been bootstrapped using certificates from the SystemRoots
keychain. To add additional certificates (e.g. the certificates added in
the System keychain), place .pem files in
/usr/local/etc/openssl/certs
and run
/usr/local/opt/openssl/bin/c_rehash
openssl is keg-only, which means it was not symlinked into /usr/local,
because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries.
If you need to have openssl first in your PATH run:
echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
For compilers to find openssl you may need to set:
export LDFLAGS="-L/usr/local/opt/openssl/lib"
export CPPFLAGS="-I/usr/local/opt/openssl/include"
==> mongodb@3.4
mongodb@3.4 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.
If you need to have mongodb@3.4 first in your PATH run:
echo 'export PATH="/usr/local/opt/mongodb@3.4/bin:$PATH"' >> ~/.bash_profile
To have launchd start mongodb@3.4 now and restart at login:
brew services start mongodb@3.4
Or, if you don't want/need a background service you can just run:
mongod --config /usr/local/etc/mongod.conf并且安装信息非常的友好,可见,不但安装了 mongodb 还顺带的安装了其依赖包 openssl,
openssl
建议通过如下命令将 openssl 的信息加入环境变量,1
echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
mongodb@3.4
首先,可见安装路径
是 /usr/local/Cellar/mongodb@3.4/3.4.17
其次,可执行文件
是放置在 /usr/local/opt/mongodb@3.4/bin 中的
再次,mongodb 的配置文件路径 /usr/local/etc/mongod.conf
最后,mongodb 提示了两种启动方式,- 通过 brew services start
- 将 mongodb bin/ 导入你的环境变量中;
brew switch
如果本地安装了多个版本,告诉 brew 我需要切换至哪个版本,比如,1
2
3
4
5
6
7
8
9
10$ brew info postgresql
postgresql: stable 9.3.2 (bottled)
http://www.postgresql.org/
Conflicts with: postgres-xc
/usr/local/Cellar/postgresql/9.1.5 (2755 files, 37M)
Built from source
/usr/local/Cellar/postgresql/9.3.2 (2924 files, 39M) *
Poured from bottle
From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/postgresql.rb
# … and some more
可以看到,本地安装了两个版本的 postgresql,9.1.5 和 9.3.2,那么如果,我们需要切换至 9.1.5 呢?执行如下命令即可,1
2
3
4$ brew switch postgresql 9.1.5
Cleaning /usr/local/Cellar/postgresql/9.1.5
Cleaning /usr/local/Cellar/postgresql/9.3.2
384 links created for /usr/local/Cellar/postgresql/9.1.5
检查,1
2
3
4
5
6
7
8
9
10$ brew info postgresql
postgresql: stable 9.3.2 (bottled)
http://www.postgresql.org/
Conflicts with: postgres-xc
/usr/local/Cellar/postgresql/9.1.5 (2755 files, 37M) *
Built from source
/usr/local/Cellar/postgresql/9.3.2 (2924 files, 39M)
Poured from bottle
From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/postgresql.rb
# … and some more
注意,后面的 * 号,表示哪个版本目前是被激活的;
brew update
1 | $ brew update |
注意,这是对 brew 自身进行 update;
brew upgrade
对某个已安装的应用程序进行更新,比如
1 | $ brew upgrade php |
表示对 php 安装包进行更新
brew cleanup
brew doctor
该命令是用来对 brew 进行健康体检的;
1 | $ brew doctor |
会检测出当前 Homebrew 存在的一些警告或者异常,下面罗列一些典型的警告,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32Warning: You have unlinked kegs in your Cellar
Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
those kegs to fail to run properly once built. Run `brew link` on these:
percona-server
Warning: Homebrew's sbin was not found in your PATH but you have installed
formulae that put executables in /usr/local/sbin.
Consider setting the PATH for example like so
echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile
Warning: Your Xcode (8.1) is outdated.
Please update to Xcode 8.2 (or delete it).
Xcode can be updated from the App Store.
Warning: Your XQuartz (2.7.8) is outdated.
Please install XQuartz 2.7.9 (or delete the current version).
XQuartz can be updated using Homebrew-Cask by running
brew cask reinstall xquartz
Warning: Some frameworks can be picked up by CMake's build system and likely
cause the build to fail. To compile CMake, you may wish to move these
out of the way:
/Library/Frameworks/libcurl.framework
Warning: Unbrewed header files were found in /usr/local/include.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected header files:
/usr/local/include/node/android-ifaddrs.h
/usr/local/include/node/ares.h
/usr/local/include/node/ares_build.h
...
brew services
安装
1 | brew tap homebrew/services |
原理
原理,https://robots.thoughtbot.com/starting-and-stopping-background-services-with-homebrew
作用范围 - login session
首先,要切记,brew services 必须是在用户通过 GUI 登录以后,才能够执行(这种情况在 Macos 中的术语叫做 login session
);否则如果在用户未 GUI 登录的情况下,通过 SSH 执行的话,会报如下的错误,Could not find domain for
1 | $ brew services start jenkins |
备注,
其实追根溯源的话,这个错误是由 launchctl 抛出来的,因为 brew services 正是通过封装 launchctl 来执行的,如果使用 launchctl 在用户未 GUI 登录的情况下,通过 ssh 执行会包同样的错误;1
2$ launchctl bootstrap gui/501 ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist
Could not find domain for
封装 launchctl
brew services 其实背后执行的是 launchctl,只是 brew services 将其底层的复杂性给封装了;那它是怎么封装了哪些步骤呢?下面以 jenkins 为例,
首先,将 jenkins 服务的描述文件 plist 拷贝到当前用户的 LaunchAgents 目录中,
1
2To have launchd start mysql at login:
ln -sfv /usr/local/opt/jenkins/*.plist ~/Library/LaunchAgents然后,通过 launchctl 加载 plist 描述文件并执行,两种执行的方式
方式一、1
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist
方式二、
1
launchctl bootstrap gui/501 ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist
可以看到,实际上 brew services 就是封装了底层的 launchctl;
plist
从上述分析可知,实际上,brew services 通过解析 plist 中的相关配置来启动的 jenkins,下面来看一下 jenkins.plist 的相关配置,
1 | <plist version="1.0"> |
可以看到,它执行的命令,是通过 java 1.8 执行的 java -jar 命令启动位于 /usr/local/opt/jenkins/libexec/ 中的 jenkins.war 启动的,其执行的时候,有两个附带的参数,既 ip 地址 127.0.0.1 和端口 8080;
brew services list
可以通过 brew list 查看相关的服务
1 | $ brew services list |
Wow,这才发现,原来我的 redis 是启动了的;难道是登陆后自启动的?
注意事项
launchctl 要求,必须是 GUI logged in 的用户才能使用,也就是必须通过界面登录以后的用户才能使用;否则,如果在用户没有 GUI 登录的情况下,执行如下命令,1
2
3$ brew services start jenkins
Could not find domain for
Error: Failure while executing; `/bin/launchctl enable gui/501/homebrew.mxcl.jenkins` exited with 112.
将会得到 Could not find domain for 的错误;
这就使得,如果你是想把 Mac 作为纯服务器来使用的话,brew services 就不是你的最佳选择了,因为很有可能,你的账户根本没有办法 GUI log in;
相关的声明周期查看 https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/Introduction.html 文章中提到了 Startup Session 和 Login Sessinon;
使用案例
升级当前 maven 为最新版本
升级 Homebrew 自己使用
update
关键字1
$ brew update
升级第三方包,使用
upgrade
关键字1
$ brew upgrade maven
输出日志如下
1
2
3
4
5
6
7
8
9
10
11
12
13Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
No changes to formulae.
==> Upgrading 1 outdated package, with result:
maven 3.3.9
==> Upgrading maven
==> Using the sandbox
==> Downloading https://www.apache.org/dyn/closer.cgi?path=maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
==> Best Mirror http://www-us.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
######################################################################## 100.0%
🍺 /usr/local/Cellar/maven/3.3.9: 95 files, 9.6M, built in 30 seconds
为系统环境创建软链接
通常,通过 homebrew 安装的应用并不能直接当做系统命令进行使用,我们往往需要在系统环境 /usr/bin 中为其创建软链接才行;
正好在研究 openssl,那么这里就以 openssl 为例来讲解
https://medium.com/@katopz/how-to-upgrade-openssl-8d005554401
ln 命令
1 | $ sudo ln -s /usr/local/Cellar/openssl/1.0.2a-1/bin/openssl /usr/bin/openssl |
报错,Operation not permitted
;
切换到 root1
$ sudo -i
1 | $ sudo ln -s /usr/local/Cellar/openssl/1.0.2a-1/bin/openssl /usr/bin/openssl |
同样报错,Operation not permitted
;
再次执行
brew link –force xxx
一般而言,通过brew link --force xxx
就可以将通过 brew 所安装的软件包直接连接到/usr/bin/
目录中;但是这里记录下openssl
的情况,
1 | $ brew link --force openssl |
可见,这里提出了一个 warning,如果更改系统的 openssl 的指向将导致系统安全风险,所以,这里不推荐这么做;google 了一下原因,
http://stackoverflow.com/questions/38670295/homebrew-refusing-to-link-openssl
brew 团队:https://github.com/Homebrew/brew/pull/597
brew 开发团队的解释,重要的部分摘要如下,
Our goals:
- MacOS users can use .NET Core
- Security updates to OpenSSL can be delivered to users independent of our release schedule
- While documentation may assume a single dependency source (e.g. homebrew), have no hard dependence on that dependency source
- Have as simple of getting started instructions as possible given preceding goals
可以通过 .NET Core 第三方独立的 openssl 环境来进行安全升级,
于是,按照 http://stackoverflow.com/questions/38670295/homebrew-refusing-to-link-openssl 中的步骤进行修改,
如果是安装的 1.0.0 NET Core,执行1
$ sudo install_name_tool -add_rpath /usr/local/opt/openssl/lib /usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.0/System.Security.Cryptography.Native.dylib
如果安装的是 1.0.1 NET Core,执行1
$ sudo install_name_tool -add_rpath /usr/local/opt/openssl/lib /usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.1/System.Security.Cryptography.Native.dylib
不过我安装的是 1.0.5,所以执行的是1
$ sudo install_name_tool -add_rpath /usr/local/opt/openssl/lib /usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.5/System.Security.Cryptography.Native.dylib
总之,都试过了,总之上述的解决方案对最新版本的 OSX 均不支持,看看 brew 开发团队的一句话彻底将我的希望浇灭了;
@drem-darios
We don’t support brew link –force openssl any more for the reasons described when you run the command.
我们不再支持通过brew link --force openssl
的方式,原因是,openssl
是与核心安全相关的,决不允许擅自更改,否则会造成全局的危险… 所以,没辙了,最后只能通过
1 | $ /usr/local/Cellar/openssl/1.0.2k/bin/openssl version |
来操作啦…
Reference
非常好的 user guide: http://friendly-101.readthedocs.io/en/latest/homebrew.html
官方 doc 以及 troubleshooting https://github.com/Homebrew/brew/blob/master/docs/Troubleshooting.md