Vấn đề này thường phát sinh khi pip cố gắng cài đặt một trang web cho IPython trên El Capitan. Cách khắc phục nhanh là sử dụng lệnh pip như thế này:
sudo -H pip install --install-option '--install-data=/usr/local' <package>
Tuy nhiên, Bảo vệ toàn vẹn hệ thống (SIP) trên El Capitan chặn một số thực tiễn xấu với pip được sử dụng để trượt, do đó bạn có thể cần thực hiện thêm một số thay đổi để giúp pip hoạt động trơn tru trên El Capitan.
SIP trên El Capitan cho thấy ba vấn đề khi sử dụng pip với phiên bản Python do Apple cung cấp trên OS X:
distutils không đặt chính xác hai biến quan trọng trên máy Mac, vì vậy pip cố gắng viết tiêu đề và các tệp được chia sẻ khác (ví dụ: manpages) bên dưới /System/Library/Frameworks/Python.framework/Versions/2.7/
. Đây là một ý tưởng tồi, nhưng trong các phiên bản trước của OS X, nó đã thành công nếu pip được chạy với sudo. Tuy nhiên, nó thất bại trên El Capitan do SIP. Đây là lỗi bạn gặp phải. Nó cung cấp các thông điệp nhưOSError: [Errno: 1] Operation not permitted: '/System/Library/Frameworks/Python.framework/Versions/2.7/share'
Apple cài đặt các phiên bản lỗi thời của một số gói trong /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/
(ví dụ: sáu). Trên các phiên bản trước của OS X, khi bạn cài đặt gói cần phiên bản mới hơn của một trong số đó, sudo pip
sẽ âm thầm xóa phiên bản cũ khỏi /System/
thư mục và cài đặt phiên bản mới hơn /Library/Python/2.7/site-packages
. Đây cũng là một ý tưởng tồi và không còn có thể với SIP. Nhưng bây giờ pip sẽ gặp sự cố với thông báo lỗi trong khi cố gắng xóa gói cũ. Tin nhắn đó cũng được OSError: [Errno: 1]
, nhưng nó đến sau một tin nhắn như thế nào Uninstalling six-1.4.1:
. Xem, ví dụ: https://github.com/pypa/pip/issues/3165 .
Phiên bản Python của Apple thêm một số thư mục /System/Library/Frameworks/Python.framework/Versions/2.7/
vào đường dẫn tìm kiếm python phía trên các vị trí cài đặt gói người dùng có thể truy cập tiêu chuẩn. Vì vậy, nếu bạn cài đặt phiên bản mới hơn của gói ở nơi khác (ví dụ sudo -H pip install --ignore-installed six
:), bạn sẽ nhận được thông báo rằng quá trình cài đặt đã thành công, nhưng sau đó khi bạn chạy python, bạn sẽ nhận được phiên bản cũ hơn /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/
. Điều này cũng làm cho không thể sử dụng các gói mới có cùng tên với các mô-đun từ thư viện chuẩn.
Bạn có thể giải quyết những vấn đề này, nhưng phương pháp phụ thuộc vào câu trả lời của bạn cho ba câu hỏi.
- Bạn có muốn tiếp tục sử dụng phiên bản Mac OS X của Python hoặc cài đặt của riêng bạn không? Cài đặt của riêng bạn là tùy chọn an toàn nhất và có thể được thực hiện thông qua trình cài đặt Python chính thức, Homebrew hoặc Anaconda. Đây cũng là những gì Apple khuyến nghị , như được chỉ ra bởi @Sacrilicy . Nếu bạn cài đặt phiên bản Python của riêng mình, có lẽ bạn nên gỡ cài đặt mọi thứ hiện được cài đặt
/Library/Python/2.7/site-packages
và bất kỳ tập lệnh nào được cài đặt /usr/local/bin
cho các gói đó (bao gồm cả pip). Nếu không, bạn sẽ có trải nghiệm khó chịu khi một số tập lệnh truy cập phiên bản Python được cài đặt hệ thống và một số truy cập cài đặt của riêng bạn.
Nếu bạn muốn gắn bó với Python được cài đặt hệ thống, thì bạn phải đưa ra hai quyết định nữa:
Bạn có muốn cài đặt các gói cho tất cả người dùng, hoặc chỉ cho chính mình? Cài đặt cho tất cả người dùng đảm bảo rằng mọi chương trình sử dụng Python (bao gồm cả các tập lệnh quản trị) sẽ có quyền truy cập vào tất cả các gói bạn cài đặt. Tuy nhiên, có một cơ hội xa rằng nó sẽ can thiệp vào việc sử dụng Python của El Capitan. (Tôi hy vọng rằng Apple sử dụng python -S
để đảm bảo họ luôn nhận được gói họ mong đợi, nhưng tôi không có cách nào để kiểm tra điều này.) Cài đặt chỉ dành riêng cho tài khoản người dùng của riêng bạn loại bỏ khả năng can thiệp vào quá trình cài đặt hệ thống Python. Lưu ý: nếu bạn định chuyển từ cài đặt toàn hệ thống sang chỉ dành cho người dùng, có lẽ bạn nên tận dụng cơ hội này để gỡ cài đặt mọi thứ hiện được cài đặt /Library/Python/2.7/site-packages
và các tập lệnh liên quan /usr/local/bin
.
Bạn có muốn ẩn các gói bổ sung được cài đặt với phiên bản OS X của Python (bên dưới /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/
) hoặc giữ chúng trong đường dẫn tìm kiếm không? Tôi khuyên bạn nên ẩn chúng, để các phiên bản mới nhất của các gói này sẽ tự động được cài đặt ở các vị trí người dùng có thể truy cập khi cần. Nếu bạn không ẩn thư mục này, đôi khi bạn sẽ nhận được thông báo rằng pip không thể xóa gói hiện có để nâng cấp lên phiên bản mới hơn (cần một gói khác mà bạn đang cài đặt). Trong trường hợp đó, bạn sẽ cần chạy pip install --ignore-installed <package>
, nó sẽ cài đặt phiên bản mới hơn và ẩn phiên bản cài đặt hệ thống. Tuy nhiên, nếu bạn che giấu toàn bộ/System/.../Extras/...
thư mục, bạn sẽ mất quyền truy cập vào một số gói Apple không có sẵn thông qua pip, tức là CoreGraphics và bonjour. (Nếu bạn cần những thứ này, bạn có thể có quyền truy cập bằng cách liên kết chúng vào thư mục gói trang web của bạn.)
Bây giờ, đây là cách giải quyết. Đây sẽ là cách thực hành tốt trên tất cả các phiên bản OS X, để tránh vô tình thay thế hoặc xóa các gói Python được sử dụng bởi hệ điều hành; tuy nhiên, chúng rất cần thiết nếu bạn muốn sử dụng các gói do người dùng cài đặt với phiên bản Python do Apple cung cấp trên OS X El Capitan (10.11).
Cài đặt pip
Bạn có thể đã làm điều này rồi, nhưng nếu không, bạn có thể sử dụng lệnh sau để cài đặt pip cho tất cả người dùng :
sudo -H easy_install pip
# pip script will be installed in /usr/local/bin
Hoặc sử dụng lệnh này để cài đặt pip cho tài khoản người dùng của riêng bạn :
easy_install --user pip
# pip script will be installed in ~/Library/Python/2.7/bin
Quản lý vị trí tệp được chia sẻ
Nếu bạn đang cài đặt các gói cho tất cả người dùng, hãy tạo một tệp có tên .pydistutils.cfg với các dòng này (từ https://github.com/pypa/pip/issues/426 ):
[install]
install-data=/usr/local
install-headers=/usr/local
Nếu bạn thường sử dụng sudo -H pip ...
, thì bạn nên đặt tệp này vào /var/root
(thư mục chính cho người dùng root). Nếu bạn thường sử dụng sudo pip ...
, thì bạn nên đặt tệp này vào thư mục nhà của riêng bạn (~).
Các cài đặt này sẽ ngăn pip cố gắng ghi các mục được chia sẻ như tiêu đề và trang hướng dẫn bên dưới /Library/System
. (Lệnh ở đầu câu trả lời này là một phiên bản nhanh hơn trong những điều tương tự.) Các thiết lập này là cần thiết bởi vì mã darwin cụ thể trong /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/command/install.py
thất bại trong việc thiết lập các biến đến các địa điểm gốc có khả năng ghi (mặc dù nó đặt biến khác một cách chính xác). Có nhiều thông tin hơn về điều này tại https://github.com/pypa/pip/issues/3177 .
Nếu bạn chỉ cài đặt các gói cho tài khoản người dùng của riêng mình, các mục được chia sẻ sẽ tự động được cài đặt bên dưới ~/Library/Python/2.7/
. Nhưng bạn nên thêm các dòng sau vào ~ / .profile để các mục được chia sẻ sẽ được tìm thấy khi bạn cần chúng:
export PATH=~/Library/Python/2.7/bin:$PATH
export MANPATH=~/Library/Python/2.7/share/man:$MANPATH
Lưu ý: bạn sẽ cần khởi động một shell mới hoặc chạy chúng trên dòng lệnh để các thay đổi có hiệu lực. Bạn cũng có thể muốn chạy hash -r
nếu gần đây bạn đã xóa các tập lệnh cũ khỏi đường dẫn.
Quản lý đường dẫn Python
Bạn sẽ cần đảm bảo rằng các gói bạn cài đặt theo thứ tự tìm kiếm của Python cao hơn các gói được cài đặt hệ thống. Cách dễ nhất để làm điều này là với .pth
các tập tin. Điều này tuân theo đề xuất của @ Sacrilicy ở những nơi khác trên trang này , nhưng đảm bảo rằng thư mục gói trang web người dùng của bạn được tìm kiếm trước thư mục gói trang web toàn hệ thống của bạn và cả hai đều được tìm kiếm trước thư viện chuẩn và thư mục Extras của Apple (cả trong / System /. ..). Nó cũng bỏ qua /System/.../Extras
từ đường dẫn tìm kiếm nếu muốn.
Tạo một tập tin được gọi fix_mac_path.pth
, với văn bản dưới đây. Nếu bạn đang cài đặt các gói cho tất cả người dùng, fix_mac_path.pth
nên được đặt trong /Library/Python/2.7/site-packages
. Nếu bạn chỉ cài đặt cho người dùng của riêng mình, fix_mac_path.pth
nên ở trong ~ / Library / Python / 2.7 / lib / python / site-gói. (Tệp này có thể có bất kỳ tên nào bạn muốn, nhưng nó phải được đặt ở một hoặc cả hai vị trí này và nó phải kết thúc bằng .pth
; ngoài ra, tất cả văn bản trong tệp này phải nằm trên một dòng.)
Nếu bạn muốn ẩn các gói do Apple cài đặt trong /System/.../Extras
:
Trước tiên hãy chạy một trong các lệnh sau để có được bản sao hoạt động của pip / setuptools độc lập với phiên bản do Apple cung cấp:
pip install --ignore-installed --user setuptools # your account only
# or
sudo -H pip install --ignore-installed setuptools # all users
Sau đó đặt mã sau fix_mac_path.pth
vào vị trí được chỉ định ở trên:
import sys; std_paths=[p for p in sys.path if p.startswith('/System/') and not '/Extras/' in p]; sys.path=[p for p in sys.path if not p.startswith('/System/')]+std_paths
Nếu bạn muốn tiếp tục sử dụng các gói do Apple cài đặt, bạn không cần phải cài đặt một bản sao khác của setuptools. Chỉ cần đặt mã sau fix_mac_path.pth
vào vị trí được chỉ định ở trên:
import sys; std_paths=[p for p in sys.path if p.startswith('/System/')]; sys.path=[p for p in sys.path if not p.startswith('/System/')]+std_paths
Sau này, bạn có thể sử dụng python -m site
để đảm bảo thứ tự tìm kiếm đường dẫn có ý nghĩa.
Cài đặt gói
Sau này, bạn sẽ có thể cài đặt các gói mới bằng một trong các lệnh sau.
Cho tất cả người dùng:
sudo -H pip install <package>
Đối với người dùng của riêng bạn:
pip install --user <package>