如何使用distutils卸载已安装的程序?

7
我已经安装了一个Python应用程序,使用以下setup.py文件:
#!/usr/bin/env python

from distutils.core import setup
from libyouandme import APP_NAME, APP_DESCRIPTION, APP_VERSION, APP_AUTHORS, APP_HOMEPAGE, APP_LICENSE

setup(
    name=APP_NAME.replace(" ","-").lower(),
    version=APP_VERSION,
    description=APP_DESCRIPTION,
    author="John G",
    author_email="xxx@gmail.com",
    url=APP_HOMEPAGE,
    license=APP_LICENSE,
    scripts=["youandme.py"],
    packages=["libyouandme"],
    data_files=[
        ('share/applications', ['youandme.desktop']),
        ('usr/share/icons/hicolor/16x16/apps', ['icons/hicolor/16x16/apps/you.png']),
        ('usr/share/icons/hicolor/22x22/apps', ['icons/hicolor/22x22/apps/you.png']),
        ('usr/share/icons/hicolor/48x48/apps', ['icons/hicolor/48x48/apps/you.png'])],
)

如何从我的Ubuntu机器上卸载此应用程序?

我可以使用distutils吗?


可能重复:https://dev59.com/iXRC5IYBdhLWcg3wG9bp - mouad
5个回答

6
安装Ubuntu的checkinstall软件包。 checkinstall监控安装过程并创建一个deb软件包。这使您可以使用常规软件包管理命令来删除软件。
首先,使用checkinstall重新安装候选Python模块/包。更改目录到包含候选Python模块/包的setup.py文件的目录:
cd <PACKAGE_NAME>

然后:

sudo checkinstall -D --fstrans=no python setup.py install

这将创建一个 .deb 包,并再次安装 python 模块。 您将被询问一些问题。默认答案应该是可以的。 (但是,如果 setup.py 文件位于 python 模块的子目录(例如“源”子目录)中,则可能会更改 .deb 包的“名称”。)
(保存的 .deb 包现在捕获了 python 包如何安装自己,dpkg 可以删除 python 包。)
然后立即删除模块:
sudo dpkg -r <PACKAGE_NAME>

附注:我听说有些安装程序与checkinstall不兼容,虽然我自己从未遇到过任何问题。


4
自pip 8.0.0版本以来,运行pip uninstall <package>时,如果<package>是预先由操作系统安装的内容(可能通过python setup.py install完成),将无法正常卸载。错误信息为:

检测到一个由distutils安装的项目('<package>'),我们无法卸载。由于distutils提供的元数据不包含已安装的文件列表,因此pip不知道要卸载哪些文件。

因此,您需要使用操作系统的包管理器来卸载这些软件包。例如,在Ubuntu中:sudo apt-get remove python-<package>可以卸载它。
我发现两个软件包存在此问题:httplib2six,上述技巧帮助我解决了该错误。希望其他人也会发现这个有用。

这帮助我降级了 sympympmath - otaku

4

据我所知,只有pip允许卸载Python模块,因此如果您没有安装它,可以使用以下命令进行安装:

sudo easy_install pip

然后使用pip卸载您的模块。
sudo pip uninstall <module_name>

其中module_name是传递给setup函数的name参数的值。

编辑:我刚看到您使用了"python-3.x"标签,目前pip还没有3.x版本,因此如果需要卸载python3.x模块,本答案不适用。


我认为pip无法卸载使用setup.py install或develop安装的包,请参考:http://pip.openplans.org/ 章节uninstall。 - mouad
@singularity:嗯,奇怪,我使用“python setup.py install”安装了许多自制库,但我总是能够使用pip将它们删除,即使pip的文档似乎告诉我不应该这样做。也许我漏掉了什么... - mdeous
是的,这听起来很奇怪,因为要让pip uninstall工作,pip会为每个安装的软件包创建元数据,以便跟踪已创建的所有文件,这样就可以在卸载时将它们删除,但distuils不会这样做。就像我在答案中所说的那样,distutils2也可以做到这一点,但他们从未编写程序将此功能添加到distutils中,您可以在这里查看:http://bugs.python.org/issue4673 - mouad

2

Disutils版本1不支持卸载命令,我在评论中还为您提供了一个链接以供查看,但只是为了提供信息,Disutils2现在支持卸载命令,他们过去的GSoC一直在研究这个问题,您可以查看此 链接

您唯一的“卸载”软件包的方法是手动删除所有文件,我可以看到您在 /usr/share 中有一些文件.. ,我不知道您是否已经知道,但在开发模块时可以使用python install.py develop,它会使更改和删除变得容易。


0
我发现在安装新版本库时,distutils没有删除不再属于该包的旧模块。它只是替换了旧的模块。这里有一个简单的例子,说明在运行设置之前如何卸载旧文件。它并不完全和完美地卸载,但可能会帮助那些有相同需求的人,或者引导您走向一个功能性的解决方法。
from distutils.core import setup
import distutils.sysconfig
from os import path
from shutil import rmtree

PACKAGE_NAME = "MyPackage"

# If found, uninstall a prior version.
# This will delete any modules that are no longer in use.
targetDirPath = path.join( distutils.sysconfig.get_python_lib(), PACKAGE_NAME )
if path.exists( targetDirPath ) :
    try :
        rmtree( targetDirPath )
        print "Removed prior package at: %s" % (targetDirPath,)
    except Exception as e:    
        print "Failed to remove prior package at: %s" % (targetDirPath,)
        print e

setup(name=PACKAGE_NAME,
      version='1.2.3',
      packages=['subpackage'] )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接