Contents
  1. 1. 问题
  2. 2. Step 1
  3. 3. Step 2
  4. 4. Step 3

这段时间在弄机器学习的事情,然后看Macbook里面的Python库有点旧,就用pip更新一下。结果抛出个异常。

问题

正常的包更新使用如下命令即可:

1
$ pip install scipy --upgrade

结果抛出下面这个异常报告

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Exception:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip/commands/install.py", line 342, in run
prefix=options.prefix_path,
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip/req/req_set.py", line 778, in install
requirement.uninstall(auto_confirm=True)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip/req/req_install.py", line 754, in uninstall
paths_to_remove.remove(auto_confirm)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip/req/req_uninstall.py", line 115, in remove
renames(path, new_path)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pip/utils/__init__.py", line 267, in renames
shutil.move(old, new)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 302, in move
copy2(src, real_dst)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 131, in copy2
copystat(src, dst)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 103, in copystat
os.chflags(dst, st.st_flags)
OSError: [Errno 1] Operation not permitted: '/var/folders/zc/hgpffx914m9fn07sw5tmn23w0000gn/T/pip-bWVMmR-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy-1.8.0rc1-py2.7.egg-info'

Step 1

Google后找到这个解决方案

1
2
3
$ sudo pip install numpy --upgrade --ignore-installed
$ sudo pip install scipy --upgrade --ignore-installed
$ sudo pip install scikit-learn --upgrade --ignore-installed

首先说明一下我的电脑环境,python2.0是系统自带的,后续手动装了pyhton3.0,相关pip操作分别使用pip **pip3 **区分。现打算把python2.0下的scipy模块升级到最新版。上述方法执结果显示是成功了,但查看scipy模块版本时发现python2.0下仍旧是旧版本,pyhton3.0下却升级到最新版了。推测可能是因系统自带的Python2.0受到SIP管理,上述方法执行时识别到此信息后就去更新python3.0下的模块。因没有对不同环境做交叉验证,以上推理或许有误,但目前能解释我遇到的情况,权且如此。

Step 2

SIP: 系统完整性保护System Integrity Protection。简单来讲就是更加强制性的保护系统相关的文件夹。开发者不能直接操作相关的文件内容。苹果官方的解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
System Integrity Protection is a security technology in OS X El Capitan that’s designed to help prevent potentially malicious software from modifying protected files and folders on your Mac.
In OS X, the “root” user account previously had no permission restrictions and could access any system folder or application on your Mac. Software gained root-level access when you entered your administrator name and password to install it and could then modify or overwrite any system file or application.
System Integrity Protection restricts the root account and limits the actions that the root user can perform on protected parts of OS X.
Paths and applications protected by System Integrity Protection include:
/System
/usr
/bin
/sbin
Apps that are pre-installed with OS X
Paths and applications that third-party apps and installers can write to include:
/Applications
/Library
/usr/local
System Integrity Protection is designed to allow modifications of these protected parts only by processes that are signed by Apple and have special entitlements to write to system files, like Apple software updates and Apple installers.
Apps that you download from the Mac App Store already work with System Integrity Protection. Other third-party software that conflicts with System Integrity Protection might be set aside when you upgrade to OS X El Capitan.
System Integrity Protection also helps prevent software from changing your startup volume. To boot your Mac from a different volume, you can use the Startup Disk pane in System Preferences or you can hold down the Option key while you reboot, and select a volume from the list.
Information about products not manufactured by Apple, or independent websites not controlled or tested by Apple, is provided without recommendation or endorsement. Apple assumes no responsibility with regard to the selection, performance, or use of third-party websites or products. Apple makes no representations regarding third-party website accuracy or reliability. Risks are inherent in the use of the Internet. Contact the vendor for additional information. Other company and product names may be trademarks of their respective owners.
Last Modified: Oct 2, 2015

找到问题的原因就可以解决相关的问题了,解决问题的方法就是关闭Mac系统的“SIP“。

具体的操作步骤,引用国外的一个牛人给出的方法 :

1
2
3
4
5
6
7
8
9
How to turn off System Integrity Protection in El Capitan
Click the  menu.
Select Restart…
Hold down command-R to boot into the Recovery System.
Click the Utilities menu and select Terminal.
Type csrutil disable and press return .
Close the Terminal app.
Click the  menu and select Restart… .

翻译过来就是:

  1. 点击Mac电脑的苹果图标
  2. 选择 重新启动
  3. 按住 command+R,直到进入还原模式
  4. 选择实用工具,然后点击 终端
  5. 输入 csrutil disable 按下回车
  6. 重启电脑

这样就将“SIP“关闭了。

然后我们使用 pip 安装升级numpy、scipy等相关的包。

问题是解决了,但是如果到这里就认为已经万事大吉了,其实是大错特错了。苹果官方之所以设置“SIP“主要是考虑到系统的安全性问题。所以,我们最好还是将“SIP“打开。打开的方式如下:

  1. 点击Mac电脑的苹果图标
  2. 选择 重新启动
  3. 按住 command+R,直到进入还原模式
  4. 选择实用工具,然后点击 终端
  5. 输入 csrutil enable 按下回车
  6. 重启电脑

Step 3

再次执行第一步的升级命令,仍旧和之前一样的结果。SIP都关了,那就大胆的去做吧,找到scipy模块的path,手动删掉,再次执行命令,结果就OK了。
因多看了一眼刚打开的Finder界面,惊奇地发现没有scipy这个模块,再次把path显示出来发现和之前的路径已经不一样了。原来系统自带的模块和手动安装的模块不在一个路径下,至于为什么这样,留待以后再去想吧,毕竟目前的问题已经解决了。

1
2
3
4
5
>>> import scipy
>>> scipy.__version__
'0.13.0b1'
>>> scipy.__path__
['/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy']
1
2
3
4
5
6
>>> import scipy
>>> scipy.__version__
'0.19.1'
>>> scipy.__path__
['/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy']
>>>
Contents
  1. 1. 问题
  2. 2. Step 1
  3. 3. Step 2
  4. 4. Step 3