在安裝Python 3.12以上版本的Linux系統,如果執行pip install
指令,可能會遇到以下錯誤:
error: externally-managed-environment
× This environment is externally managed ╰─> To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install.
error: externally-managed-environment
或者「外部管理的環境」這個錯誤見於新版的Ubuntu 24.04、Debian 12、Arch Linux、Fedora、openSUSE、Raspberry Pi OS 12等系統,macOS的Homebrew用戶可能也會遇到。
老實說這個不是錯誤,是開發者故意設計的行為,詳細見2021年的PEP 668提案內容。這樣做是為了防止Python的套件跟Linux系統套件管理員衝突。有時候pip一裝個新套件,便可能讓Linux系統的APT套件與Python的套件相衝突。或者依賴Python程式的套件可能因為Python版本更新而壞掉。
但是這樣就不能pip install了呀!而且寫Pyhton無法直接import模組,會出現ModuleNotFoundError: No module named
錯誤,很是麻煩!
該怎辦?這有很多種解決方法。就Linux系統維護的角度來看,不建議強行破除此限制。建議學習改用較為安全的Python套件安裝方式。
下面會提供暫時的解決方法,並探討替代的Python套件安裝法。
1. 暫時的解決方法:允許pip變更系統#
恢復到以前模式,允許pip在系統安裝套件。這個方法可能會讓Python破壞Linux系統依賴,請小心。
- 確認系統Python版本,撰文當下是3.12
python3 --version
- 將
/usr/lib/python版本/EXTERNALLY-MANAGED
檔案重新命名,這樣就不會觸發error: externally-managed-environment
警告了。
sudo mv /usr/lib/python3.12/EXTERNALLY-MANAGED /usr/lib/python3.12/EXTERNALLY-MANAGED.old
- 另一個作法是加上
--break-system-packages
引數,強制pip安裝:
sudo pip install <套件名稱> --break-system-packages
儘管用pip install <套件名稱> --user
指令也可以,不過這是將Pyhton套件安裝到使用者目前的家目錄,只有目前使用者執行的Python程式能夠import模組。假若Python程式需要使用sudo執行,則又會遇到ModuleNotFoundError: No module named
找不到套件的問題。
2. 改用Linux套件管理器安裝Python套件#
pip不能變更系統,那就透過Linux發行版套件管理員代勞吧。仔細看文章一開頭提到的error: externally-managed-environment
訊息,它也建議你使用apt install的方式安裝Python套件。
有些受歡迎的Python套件,Linux發行版會將之打包為套件,通常這些套件會以python-套件名稱
開頭。
譬如Cython,Ubuntu有將其打包,可以透過APT套件庫安裝,不需要透過pip:
sudo apt install cython
安裝後全系統可用,Python指令稿裡面就能直接import cython
模組了。
因為這些套件是Linux發行版管理員維護的,穩定性有保障,能夠確保裝下去不會破壞系統依賴。但Linux發行版收錄的Python套件可能會偏舊,無法任意切換版本。
3. 改用Python虛擬環境安裝pip套件#
使用Python官方文件提及的虛擬環境 (virtual environment) 功能,也就是安裝Python套件前都先用venv建立一個虛擬環境,讓Python的套件跟Linux系統套件隔離,再於裡面使用pip安裝想要的套件。如此一來系統就不怕被pip弄壞,還可以防止不同專案的Python套件互相衝突。
Python虛擬環境跟pip直接安裝套件到Linux系統有什麼差?請看下圖分解,以使用cython為例:如果你用apt install安裝cython,屬於系統全域安裝,不論是哪一個使用者執行Python程式,都可以import cython。但若是在venv虛擬環境裡面pip install,就只有進入虛擬環境裡面才能import cython。
註:此處使用最簡單的Python venv建立虛擬環境,依賴Linux系統所安裝的Python,不能任意切換Python版本。若要切換多重Python版本,請裝其他Python環境管理工具,例如uv、Conda、Pipx、Poetry等等。
- 從Linux發行版套件庫安裝Python虛擬環境工具
sudo apt install python3-venv
- 使用
python3 -m venv
指令,在家目錄建立一個叫做venv的虛擬環境,實際上就是一個新目錄:
cd ~
python3 -m venv venv
註解:如果你使用的Python專案來自Github,那麼也可以在git clone之後,於git儲存庫的目錄直接建立venv虛擬環境。
- 然後用source指令,讀取venv目錄下的
activate
指令,進入虛擬環境,終端機的提示符前方應該會變成(venv)
source venv/bin/activate
- 查看Python路徑為何,這裡顯示的應該是venv開頭的路徑,也就是虛擬環境裡面的Python,而非Linux系統目錄的
/usr/bin/python3
which python3
- 然後就可以用pip install安裝套件了,例如這裡我安裝yt-dlp。所有pip install安裝的套件都會跑到
venv
這個虛擬環境的目錄下。
pip install yt-dlp
- 日後要執行虛擬環境裡面的程式,建議進入虛擬環境裡面操作:
source venv/bin/activate
yt-dlp --version
- 需要執行.py程式的場合,直接用python3指令就可以了
python3 main.py
- 或者直接填寫絕對路徑,呼叫虛擬環境裡面的Python執行.py程式,就不需要使用source指令啟動虛擬環境了:
./venv/bin/python3 main.py
4. 改用pipx安裝單一Python程式#
這種方式適合習慣pip install命令行程式的用戶。
你可能會覺得Python虛擬環境比pip install還麻煩了呀!每次都要跑一次進入虛擬環境的指令。
如果你想裝的Python程式是「單個程式」,希望Python pip套件安裝後可以直接從命令行執行?此時「pipx」就是一個好用的工具。它指令長得跟pip install很像,會給每個安裝的Python套件自動建立虛擬環境,並連結到對應的執行檔。這樣我們就能無縫使用新安裝的Python程式。
- 參照Github指示,從Linux套件庫安裝pipx:
sudo apt install pipx
- 讓pipx將必要路徑加入環境變數
pipx ensurepath
- 這樣就可以用pipx安裝原本pip install的套件了,例如yt-dlp
pipx install yt-dlp
- 安裝後可直接從命令行使用
yt-dlp --version
一些技術性細節:
- pipx安裝的套件預設會放到
~/.local/bin
,這裡存放的是各個Pyhton套件的符號連結檔,實際會指向~/.local/share/pipx/venvs/
目錄的虛擬環境。因為~/.local/bin
被加入環境變數,所以使用者才能從命令行執行pipx安裝的程式。 - pipx所安裝的套件只有目前使用者可用。若要讓全系統使用者可用,需要使用
pipx ensurepath --global
。 - 如果你需要在pipx建立的虛擬環境額外安裝Python套件,請使用
pipx inject <虛擬環境名稱> <Python套件名稱>
的指令安裝。 - pipx沒有切換Python版本的功能,只能使用系統的Python。