删除dragonplayer会导致同时删除很多东西

peter@debian:~$ sudo apt remove dragonplayer
[sudo] peter 的密码:
正在读取软件包列表… 完成
正在分析软件包的依赖关系树
正在读取状态信息… 完成
下列软件包是自动安装的并且现在不需要了:
ant ant-contrib ant-optional apper apper-data ca-certificates-java
coinor-libcbc3 coinor-libcgl1 coinor-libclp1 coinor-libcoinmp1v5
coinor-libcoinutils3v5 coinor-libosi1v5 cups-pk-helper default-jre
default-jre-headless espeak-ng-data firebird3.0-common
firebird3.0-common-doc firebird3.0-server-core firebird3.0-utils
fonts-crosextra-caladea fonts-crosextra-carlito fonts-liberation2
fonts-opensymbol fonts-sil-gentium fonts-sil-gentium-basic
gir1.2-atspi-2.0 gir1.2-gst-plugins-base-1.0 gir1.2-gstreamer-1.0
gir1.2-notify-0.7 gir1.2-polkit-1.0 gir1.2-wnck-3.0 hyphen-en-us
java-common kdeaccessibility kmag kmousetool kmouth libabw-0.1-1
libactivation-java libaopalliance-java libapache-poi-java
libapache-pom-java libargs4j-java libasm-java
libatinject-jsr330-api-java libatk-adaptor libatk-wrapper-java
libatk-wrapper-java-jni libbase-java libbcmail-java libbcpkix-java
libbcprov-java libboost-date-time1.67.0 libboost-iostreams1.67.0
libbsh-java libcdi-api-java libcdr-0.1-1 libcglib-java
libclucene-contribs1v5 libclucene-core1v5 libcmis-0.5-5v5
libcodemodel-java libcommons-cli-java libcommons-codec-java
libcommons-collections3-java libcommons-collections4-java
libcommons-compress-java libcommons-io-java libcommons-lang3-java
libcommons-logging-java libcommons-math3-java
libcommons-parent-java libcurvesapi-java libdom4j-java libdotconf0
libdtd-parser-java libe-book-0.1-1 libehcache-java libel-api-java
libeot0 libepubgen-0.1-1 libespeak-ng1 libetonyek-0.1-1
libexttextcat-2.0-0 libexttextcat-data libfastinfoset-java
libfbclient2 libflute-java libfonts-java libformula-java
libfreehand-0.1-1 libgeronimo-annotation-1.3-spec-java
libgeronimo-interceptor-3.0-spec-java libguava-java libguice-java
libhawtjni-runtime-java libhsqldb1.8.0-java libhttpclient-java
libhttpcore-java libib-util libicu4j-java
libintellij-annotations-java libistack-commons-java libitext-java
libjansi-java libjansi-native-java libjaxb-api-java libjaxb-java
libjaxen-java libjcommon-java libjdom1-java
libjetbrains-annotations-java libjsoup-java libjsp-api-java
libjsr305-java liblangtag-common liblangtag1 liblayout-java
libloader-java liblog4j1.2-java liblouis-data liblouis17
libmail-java libmaven-file-management-java libmaven-parent-java
libmaven-resolver-java libmaven-shared-io-java
libmaven-shared-utils-java libmaven3-core-java libmhash2
libmspub-0.1-1 libmwaw-0.3-3 libmythes-1.2-0 libnumbertext-1.0-0
libnumbertext-data libodfgen-0.1-1 liborcus-0.14-0
libpagemaker-0.0-0 libpcaudio0
libpentaho-reporting-flow-engine-java libpixie-java
libplexus-archiver-java libplexus-cipher-java
libplexus-classworlds-java libplexus-component-annotations-java
libplexus-interpolation-java libplexus-io-java
libplexus-sec-dispatcher-java libplexus-utils2-java libpq5
libqaccessibilityclient-qt5-0 libqxp-0.0-0 libraptor2-0 librasqal3
librdf0 librelaxng-datatype-java libreoffice
libreoffice-avmedia-backend-gstreamer libreoffice-base
libreoffice-base-core libreoffice-base-drivers libreoffice-calc
libreoffice-common libreoffice-core libreoffice-draw
libreoffice-help-common libreoffice-help-en-us libreoffice-impress
libreoffice-java-common libreoffice-kde5 libreoffice-librelogo
libreoffice-math libreoffice-nlpsolver libreoffice-report-builder
libreoffice-report-builder-bin libreoffice-script-provider-bsh
libreoffice-script-provider-js libreoffice-script-provider-python
libreoffice-sdbc-firebird libreoffice-sdbc-hsqldb
libreoffice-sdbc-postgresql libreoffice-style-breeze
libreoffice-style-colibre libreoffice-style-tango
libreoffice-wiki-publisher libreoffice-writer librepository-java
librevenge-0.0-0 librngom-java libsac-java libsaxonhe-java
libserializer-java libservlet-api-java libservlet3.1-java
libsisu-guice-java libsisu-inject-java libsisu-ioc-java
libsisu-plexus-java libslf4j-java libsnappy-java libsnappy-jni
libsonic0 libspeechd2 libstaroffice-0.0-0 libstartup-notification0
libstax-ex-java libstreambuffer-java libtxw2-java libvisio-0.1-1
libwagon-http-java libwagon-provider-api-java libwebsocket-api-java
libwnck-3-0 libwnck-3-common libwpd-0.10-10 libwpg-0.3-3
libwps-0.4-4 libxerces2-java libxml-commons-external-java
libxml-commons-resolver1.1-java libxml-java libxmlbeans-java
libxmlsec1 libxmlsec1-nss libxom-java libxres1 libxsom-java
libxz-java libzmf-0.0-0 lp-solve mythes-en-us node-normalize.css
openjdk-11-jre openjdk-11-jre-headless orca policykit-1-gnome
python3-brlapi python3-cups python3-cupshelpers python3-gst-1.0
python3-louis python3-pyatspi python3-smbc python3-speechd
python3-uno sound-icons speech-dispatcher
speech-dispatcher-audio-plugins speech-dispatcher-espeak-ng
system-config-printer system-config-printer-common
system-config-printer-udev task-desktop uno-libs3 ure x11-apps
x11-session-utils xbrlapi xinit xorg
使用’sudo apt autoremove’来卸载它(它们)。
下列软件包将被【卸载】:
dragonplayer kde-standard task-kde-desktop
升级了 0 个软件包,新安装了 0 个软件包,要卸载 3 个软件包,有 0 个软件包未被升级。
解压缩后将会空出 2,694 kB 的空间。
您希望继续执行吗? [Y/n] n


感觉这是不愿意让我删除dragonplayer,如果删除,它就把其它东西也一起删除,有点像绑架啊~

软件包task-kde-desktop依赖于软件包kde-standard,而软件包kde-standard依赖于软件包dragonplyer。因此,要求删除软件包dragonplyer会删除软件包dragonplyer、软件包task-kde-desktop和软件包kde-standard,并因此将它们的大多数依赖标记为自动删除(因为不再有软件包依赖于它们)。

我以为dragonplayer就只是一个视频播放器~

问题在于Debian Installer安装桌面的工作方式是通过task-*-desktop软件包,如果你要求删除它的某个依赖,由于破坏了依赖关系,它会要求删除task-*-desktop软件包,既而,整个桌面环境会被标记为自动删除。
这样做的好处之一是,如果你想删除桌面环境,只需要简单地删除task-*-desktop软件包后运行apt autoremove。不幸的是,从反面来讲,这也会导致一个问题——如果你想违背其依赖关系(即你想删除它所依赖的软件包),task机制就会对你无效。在这种情况下,你必须允许相关的元包被删除,然后手动执行命令apt-mark manual package_name以解除相关包的自动删除状态。
参见
https://wiki.debian.org/tasksel

我大概能够理解逻辑关系,但不太能接受。因为在我看来,这种对于视频播放器的依赖,明显是主观的人为因素,而不是因为去掉视频播放器就会导致桌面无法使用或无法启动。

我能看到的明显好处是,开箱即用:装好后用户马上就可以播放视频。

这是一个痛点~

问题在于,通常用户接触到tasksel是在执行安装程序时,如果用户发现安装完成后他们必须手动安装视频播放器的话……而且task-*软件包这种元包本来就是人造的。这里的困难在于你事先不可能知道用户需要安装什么软件包……

3个很多吗?你从来不看manual吗?输出信息也经常不看?
apt remove就只卸载相互依赖的包,autoremove才会把那一堆孤立包一并卸载。
输出信息经常不看是吧?
apt remove这类基础命令,从manpage到handbook,到处都有提到用法用例,都会说得清清楚楚,一个也不看是吧?
https://manpages.debian.org/stable/apt/apt-get.8.en.html
https://debian-handbook.info/browse/stable/sect.apt-get.html#sect.apt.install

这就是deb系发行版普遍存在的一个问题:依赖关系太过于紧密。从一定道理来说,deb系发行版依赖关系紧密可以让初学者安装软件包不需要过多担心依赖问题,可以装完一个软件包后这个软件立马可以用。但是,过于紧密的依赖关系,就会导致有时候卸载软件包时还会一起删除其他软件包组件,而这些要一起删除的软件包有时候又不能删除(尤其是桌面图形环境软件包),所以这时候要仔细阅读他要连带一起删除的软件包的名称,如果是带有gnome desktop kde plasma等桌面环境字眼的字样的就要加倍小心了,可以选择No取消操作。

顺带一提,arch linux就可以自由删除不想要的东西。Arch linux依赖关系很自由松散,可以不想要什么kde软件就删除什么。

Arch是通过软件包组解决这个问题的。
Meta package and package group - ArchWiki (archlinux.org)
软件包组只是一个包列表,所以用户能够选择安装其中的一部分包或删除其中的一部分包而不影响其他包。但是,如果软件包组包含新的成员,将不会在更新时自动安装它们。

我之前一直认为,可以autoremove的包,肯定是系统已经不使用的包,留着仅仅是占用磁盘空间而已,完全可以直接删除,比如一些库~

不过我刚才用虚拟机测试了一下,如果不执行autoremove,那么那些被提示无用的包,其实是可用和能用的状态,比如libreoffice,仍然可以打开并编辑odt文件。

这个情况让我有些困惑。

我专门对比了一下提示的中英文版,中文版说“下列软件包是自动安装的并且现在不需要了”,英文版说“The following packages were automatically installed and are no longer required”。从字面上理解,这些包应该是已经没用了,我理解为等同于不可用

但事实上这些包仍然处于可用和能用的状态,且对我来说是有用的。这有点绕,大概可以理解为,在执行apt remove dragonplayer时,我只想删除dragonplayer这一个应用,仍然希望保留和使用libreoffice,但以为apt remove dragonplayer会导致libreoffice不能使用。

到这里,我并没有产生一个需求:查看apt remove和apt autoremove的说明,因为字面的意思我理解了,只不过,我理解了,提示所表达的意思,完全不是我所理解的意思~

实际上,我从apt remove和apt autoremove的说明里,并没有找到能够纠正我的错误解理的相关说明。所以,我怀疑,这样的理解应该来自于其它地方,但具体源头是哪,不好找了。我猜测,应该会有其他人和我有相同的感觉~

谢谢你的提示,尽管让我感觉有些不舒服,但确实纠正了我的错误~
也很开心,原来有更多人在关注这里的帖子~

我之前有一个习惯,就是在执行apt remove的时候,一定会加上apt autoremove;看来以后要改掉这个习惯了。像@ mkm19940608提到的,我有点印象,有一次确实把桌面环境给误删除了,当时以为是bug,没太在意~

From apt(8)

autoremove is used to remove packages that were automatically installed to satisfy dependencies for other packages and are now no longer needed as dependencies changed or the package(s) needing them were removed in the meantime.

You should check that the list does not include applications you have grown to like even though they were once installed just as a dependency of another package. You can mark such a package as manually installed by using apt-mark(8). Packages which you have installed explicitly via install are also never proposed for automatic removal.

autoremove 是用来删除那些为了满足其他软件包的依赖关系而自动安装的软件包,现在由于依赖关系的改变或者需要它们的软件包被删除而不再需要了。

你应该检查列表中是否包括你已经喜欢的应用程序,尽管它们曾经只是作为另一个软件包的依赖关系而安装。你可以通过使用apt-mark(8)将这样的软件包标记为手动安装。你通过 install 明确安装的软件包也不会被建议自动删除。

所以,“The following packages were automatically installed and are no longer required”仅仅意味着这些软件包被标记为自动安装并且没有软件包依赖于它们。对于包管理器满足依赖关系的职能而言,它们已经成为不必要的,但是对于用户则未必如此。

看来我看的还是不够全面和仔细~

如果进一步的话,我在想能不能这么理解:

“The following packages were automatically installed and are no longer required”更应该是针对所谓的库文件而言,比如我安装scribus这个应用,它会需要安装一些必须的依赖,这些依赖如果不存在,那么scribus就无法正常使用。

而因为要做“开箱即用”,所以“依赖”已经不仅仅是上面提到的“必须”关系,而是人文关系。

翻译做一些修改,更面向用户,会不会有用?

依赖的正式定义在 7. Declaring relationships between packages — Debian Policy Manual v4.5.1.0

Depends

This declares an absolute dependency. A package will not be configured unless all of the packages listed in its Depends field have been correctly configured (unless there is a circular dependency as described above).

The Depends field should be used if the depended-on package is required for the depending package to provide a significant amount of functionality.

The Depends field should also be used if the postinst or prerm scripts require the depended-on package to be unpacked or configured in order to run. In the case of postinst configure, the depended-on packages will be unpacked and configured first. (If both packages are involved in a dependency loop, this might not work as expected; see the explanation a few paragraphs back.) In the case of prerm or other postinst actions, the package dependencies will normally be at least unpacked, but they may be only “Half-Installed” if a previous upgrade of the dependency failed.

Finally, the Depends field should be used if the depended-on package is needed by the postrm script to fully clean up after the package removal. There is no guarantee that package dependencies will be available when postrm is run, but the depended-on package is more likely to be available if the package declares a dependency (particularly in the case of postrm remove). The postrm script must gracefully skip actions that require a dependency if that dependency isn’t available.

可以看出,通常依赖都是由于要求支持安装的软件包而安装。但是在tasksel这里出现的问题是:task-*-desktop这种元包的依赖不是由于支持它而安装,它本身就是为了安装这些依赖而设计的。这就在概念上产生了一个颠倒,用户的问题是他们不能区分这两者。


修改翻译可能有助于向用户解释这个问题,但是更重要的是解决问题。当用户遇到这个问题时,他们已经在试图突破tasksel 机制了,我认为目前最好的方法是在apt中复制pacman的软件包组功能以支持更多自定义。

在apt中复制pacman的软件包组功能以支持更多自定义
@mkm19940608 Arch linux依赖关系很自由松散,可以不想要什么kde软件就删除什么。

这倒提醒我了,我入门时选择的第一个发行版是arch linux,应该是那个时候对于“不再需要的依赖”形成了一个先入为主的理解,然后转到debian后,仍按arch的理解来看待debian。这应该是"理解错误"的来源了~

From Meta package and package group - ArchWiki (archlinux.org):

group:

  • Package groups will prompt users to select the packages from the group that they wish to install (see pacman#Installing package groups).
  • Users cannot uninstall a group, because they installed a list of packages. Instead, tries to remove all members of the group.pacman -R groupname
  • New group members will not be automatically installed.
  • Users can choose which group members they wish to install.
  • Users can uninstall group members without having to remove the entire group.

对于元软件包而言,这里没有什么不一样的地方。Debian缺少的是软件包组,通过它可以安装软件包列表中的软件包。由于仅仅是软件包列表,所以允许部分安装和部分删除。当然,如果新的软件包进入软件包组,它在更新时也不会自动安装。

事实上,这里讨论的问题的核心不是依赖关系的粒度,而是提供一组软件包时的策略。在Arch中,如果你通过安装元包plasma-metakde-applications-meta安装KDE桌面,你一样会遇到类似问题。但是,通常的建议是安装软件包组plasmakde-applications,因为它们在管理时更加灵活。你的错误可能不在于错误理解了依赖关系,而在于混淆了元包和软件包组的区别。

我确实没有软件包组的概念,只停留在软件包这里~

或者说,我默认debian也像arch一样使用了软件包组进行管理~

学习了