pip freeze 列出通過 pip 解除安裝,然後通過 Pacman 重新安裝的軟體包
因為我聽說通過
pip
而不是通過包管理器安裝包是一個非常糟糕的主意,所以我試圖確定我通過pip
它安裝的所有包,這些包也可以在pacman
’s 的官方儲存庫中輕鬆獲得。並不是所有的都是(我知道我可以自己探索 AUR 或打包它們,但現在我正試圖留在官方儲存庫中),所以我暫時保留其中一些安裝pip
,並遷移休息到pacman
。我的(誠然原始的)工作流程是:
pip freeze | less
; 選擇要遷移的包(基本上是任意的)pacman -Ss python-packagename
(如果找不到,中止並使用不同的包重試)sudo pip uninstall packagename
sudo pacman -S python-packagename
- 如果
pacman
報告文件衝突,請對所有依賴包重複步驟 2 到 4,然後在目標包上重新嘗試步驟 5。這是可行的,因為我相信我現在已經成功地管理了包
pacman
-pacman -Ql python-packagename
列出了看起來正確的文件,而且有趣的是,我也看到包更新過pacman
,這表明它pacman
已經接管了更新包的責任。但是,問題在於它
pip freeze
仍然列出了這些包,即使它們已經通過pip
.例如,兩者
pip freeze | grep pylint
和都pacman -Qqe | grep pylint
表示軟體包已安裝。我可以通過其中一個sudo pacman -Rs python-pylint
或通過sudo pip uninstall pylint
.如果我這樣做 -通過
pip
或通過pacman
pip freeze
解除安裝包 - 包將從列表中消失,並且pacman -Qqe
不再找到任何東西。如果我通過 重新安裝包pacman -S
,則包會重新出現在pip freeze
. 通過重新安裝包pip
不會提示它重新出現在pacman -Qqe
.
pip
通過執行解除安裝軟體包sudo pip uninstall packagename
,然後使用--user
標誌 (iepip install --user packagename
) 重新安裝它會導致sudo pip freeze
不顯示該軟體包,而是pip freeze
繼續顯示它。通過重新安裝包pacman
會導致它重新出現在兩個列表中。我不認為這個問題與此連結上的問題重複;在那個問題中,使用者無法
pip freeze
通過解除安裝軟體包來刪除它們,並且該問題被跟踪到多個不同的pip
二進製文件。在這種情況下,通過解除安裝軟體包
pip
確實會將其從 中刪除pip freeze
,which pip
並且sudo which pip
具有相同的輸出:/usr/bin/pip
. 此外,sudo pip freeze
並pip freeze
產生相同的輸出。但是,上面連結的問題的公認答案提出的測試表現出我認為奇怪的行為。(在執行以下測試時,
pylint
已從 解除安裝pip
並重新安裝pacman
。)$ python -c 'import pkg_name' &> /dev/null && echo installed || echo not installed Using config file /home/[my user name]/.pylintrc not installed
該軟體包確實已安裝 - 它不僅列印配置文件行,而且我可以正常使用該軟體包(
pylint foo.py
)。那麼我不希望測試列印installed
嗎?要解決我關於這個問題的實際問題:
- 我可以做些什麼來確定哪些軟體包實際上是僅通過 安裝的
pip
,哪些是通過pip
和安裝的pacman
?- 可以做些什麼來糾正更廣泛的問題:
pip
跟踪通過安裝的包pacman
?
我編寫了一個 python 腳本(gist 連結)來檢查所有 python 包是否安裝了
pacman
.安裝
下載腳本並使其可執行:
$ wget https://gist.github.com/hoefling/314565368a66c308b4d7d407a3028cb7/raw/7b81553fa0a84b92a90fbaa0746482d0ec18516c/pip-query -O pip-query $ chmod +x pip-query
用法
base/archlinux
這是一個在我安裝的 docker 容器中呼叫它的範例,python-pip
並且python-wheel
:$ ./pip-query Package Version Owner ---------- ------- ----------------- appdirs 1.4.3 python-appdirs packaging 17.1 python-packaging pip 9.0.1 python-pip pyparsing 2.2.0 python-pyparsing setuptools 39.2.0 python-setuptools six 1.11.0 python-six wheel 0.31.1 python-wheel
輸出類似於 的輸出
pip list --format=columns
,但有一個額外的列Owner
列印擁有 python 包的系統包的名稱。讓我們使用直接安裝的軟體包進行測試
pip
:$ sudo pip install tqdm ... $ ./pip-query Package Version Owner ---------- ------- ----------------- appdirs 1.4.3 python-appdirs packaging 17.1 python-packaging pip 9.0.1 python-pip pyparsing 2.2.0 python-pyparsing setuptools 39.2.0 python-setuptools six 1.11.0 python-six tqdm 4.23.4 wheel 0.31.1 python-wheel
該
Owner
列的行中有一個空單元格tqdm
,這表明tqdm
不是由 安裝的pacman
。解除安裝:tqdm
_pip
$ sudo pip uninstall -y tqdm
並安裝它
pacman
:$ pacman -S python-tqdm
永久安裝
如果您願意,請將
pip-query
文件放在您的PATH
.$HOME/.local/bin
$ pip-query
適應其他包管理器
如果您願意,調整腳本以與其他包管理器一起使用應該很容易。例如,如果我更改
['pacman', '-Qqo', file]
為['qfile', '-q', file]
,腳本將在 Gentoo 上執行而無需任何進一步修改*。如果您的包管理器不支持純包名稱列印,請out
使用正則表達式或其他方式從字元串中提取相關資訊。批量重新安裝軟體包
pacman
您可以修改
pip-query
或遵循 Unix 哲學並編寫一些為您重新安裝的 bash 命令。但是,您必須處理由pacman
(如下例所示)提出的多個建議,並在沒有任何建議的情況下實施這種情況。這是我的謙虛嘗試(不是 bash 專家):$ ./pip-query | tail -n +3 | while read line ; do split=(${line}); \ > if [ "${#split[@]}" -eq "2" ]; then pkgname=${split[0]}; \ > echo -e "Suggestion: pip uninstall -y $pkgname && pacman -S $(pacman -Sspq $pkgname | tr '\n' ' ')"; \ > fi; done Suggestion: pip uninstall -y tqdm && pacman -S python-tqdm python2-tqdm
增強這一點,您就有了重新安裝任務的自動化解決方案。
*:假設
app-portage/portage-utils
出現。