OS X 10.11 El Capitan 如何升级系统预装python

by Liu Yue/2015-10-17
最近升级OSX到El Capitan。发现mvn、Python的配置几乎全部失效了。

直接上解决方案
安装homebrew

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安装Python3
使用homebrew进行下载:

brew install python3
建立新的命令符号链接
# 进入/usr/local/bin
cd /usr/local/bin

# 创建新的命令符号链接
ln -s /usr/local/Cellar/python3/3.4.3_2/bin/python3 /usr/local/bin/python
ln -s /usr/local/Cellar/python3/3.4.3_2/bin/pip3 /usr/local/bin/pip
ln -s /usr/local/Cellar/python3/3.4.3_2/bin/pydoc3.3 /usr/local/bin/pydoc
ln -s /usr/local/Cellar/python3/3.4.3_2/bin/pythonw3.3 /usr/local/bin/pythonw
ln -s /usr/local/Cellar/python3/3.4.3_2/bin/python3.3m-config /usr/local/bin/python-config

# 测试,即可查看是否是最新版本
python -V

分析
System Integrity Protection

大部分人在采用类似前言给出的教程时,假如是OS X El Capitan之前的版本,基本不会遇到什么问题。但是,在OS X El Capitan中,Apple加入了一个新的安全机制,即:System Integrity Protection(简写SIP)。

众所周知,基于FreeBSD的OS X与*unix一样拥有root账号。在OSX 10.11之前,root用户拥有完全的控制权,可以对系统的任何文件和应用进行修改。当程序获root权限之后,就可以对系统进行修改,这在无形中,存在安全隐患。为了增强系统安全,Apple在El Capitan中引入System Integrity Protection,用于限制root账号的权限。

System Integrity Protection,保护的目录和应用程序包括:

/System
/usr,除/usr/local子目录
/bin
/sbin
系统预装的应用程序
允许第三方安装和修改的目录:

/Application
/Library
/usr/local
网上常见的文章都是通过直接在/usr或者/bin中创建或者替换原有的Python的命令符号链接。而这些目录刚好是SIP的保护的目录。
因此,取而代之,应该采用上面展示的方式,**在/usr/local/bin中创建Python的命令符号链接**,而不再是/usr或者/bin。

PATH变量

在上面的做法中,并没有删除预装的Python命令或者链接。那我们如何保证在命令行中调用python时,系统调用的是哪一个程序呢?

这个就得提到PATH变量了。

在操作系统中,PATH变量是一个通知shell查找执行命令的目录的环境变量。使用环境变量可以快速地找到执行命令,同时,在一定程度上也保证了系统的安全。大部分系统在安装时,就会设置一个默认的PATH路径。

当我们输入一个命令时,系统将会依次在PATH变量中规定的目录(用:分隔)进行搜索,直到找到第一个符合的命令。在大部分的系统中PATH的初始变量如下:

PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
在上述的操作中,我们在/usr/local创建了命令链接,所以当我们输入python时,系统会调用/usr/local中,而非/usr/bin中的python命令。

根据PATH变量的这种特性,有时候为了少点麻烦,可以直接将相应的软件的bin目录加到PATH变量中,如配置maven环境变量:

# 编辑相应的shell的配置文件,如用户目录下的.zshrc文件:
vim ~/.zshrc

# 添加如下语句:
export PATH=/usr/local/Cellar/maven/3.3.3/bin:$PATH
利用PATH配置变量的其他玩法