问题描述
根据手册页:
-
apt
具有参数full-upgrade
-
apt-get
具有参数dist-upgrade
。
两者是同一个命令吗?
顺便说一句:Ubuntu 16.04 中官方推荐的命令是什么? apt
或 apt-get
?
最佳回答
apt full-upgrade
执行与 apt-get dist-upgrade
相同的功能。
man apt
\\n
full-upgrade (apt-get(8)) performs the function of upgrade but will remove currently installed packages if this is needed to upgrade the system as a whole.
\\n
man apt-get
\\n
dist-upgrade in addition to performing the function of upgrade, also intelligently handles changing dependencies with new versions of packages; apt-get has a “smart” conflict resolution system, and it will attempt to upgrade the most important packages at the expense of less important ones if necessary. The dist-upgrade command may therefore remove some packages. The\\n/etc/apt/sources.list file contains a list of locations from which to retrieve desired package files. See also apt_preferences(5) for a mechanism for overriding the general settings for\\nindividual packages.
\\n
次佳回答
是的,它们是相同的命令。 apt的cmdline/apt.cc的这部分证明了这一点:
static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
{
return {
// [snip]
// system wide stuff
{"update", &DoUpdate, _("update list of available packages")},
{"upgrade", &DoUpgrade, _("upgrade the system by installing/upgrading packages")},
{"full-upgrade", &DoDistUpgrade, _("upgrade the system by removing/installing/upgrading packages")},
// misc
{"edit-sources", &EditSources, _("edit the source information file")},
{"moo", &DoMoo, nullptr},
// for compat with muscle memory
{"dist-upgrade", &DoDistUpgrade, nullptr},
// [snip]
};
}
为了完整起见, cmdline/apt-get.cc :
static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
{
return {
// [snip]
{"dist-upgrade", &DoDistUpgrade, _("Distribution upgrade, see apt-get(8)")},
{"full-upgrade", &DoDistUpgrade, nullptr},
// [snip]
};
}
对于 apt
和 apt-get
, full-upgrade
和 dist-upgrade
都引用相同的 DoDistUpgrade
函数,因此执行相同的操作,只是 apt
在此处具有不同的默认选项:
\\n
After packages are successfully installed by apt(8), the corresponding .deb package files will be removed from the /var/cache/apt/archives cache directory
\\n
APT::Keep-Downloaded-Packages
可以控制 apt-get
的此行为。
奖金调查
@Lii 提出了一个很好的观点,即 DoDistUpgrade
可以根据所使用的二进制文件(即 argv[0]
)采取不同的行为。该代码比我预期的要简单得多,因为需要考虑很多层和全局变量,但让我们看一下。
ParseCommandLine
函数用于这两个二进制文件。该函数执行命令行可能产生影响的以下步骤:
-
InitLocale(Binary)
: 所有情况都使用相同的代码。\n -
pkgInitConfig(**Cnf)
: 所有情况都使用extern Configuration *_config
全局变量。\n -
BinarySpecificConfiguration(argv[0])
:现在这很有趣。apt
具有这些与apt-get
不同的有意义的默认选项:\n
-
APT::Get::Upgrade-Allow-New = true
。这是默认启用的--with-new-pkgs
到apt-get
选项。这在apt
的手册中有记录,但这里的影响仅对upgrade
命令。 -
APT::Keep-Downloaded-Packages = false
。这是apt
和apt-get
之间的实际差异,并在 NEWS file 中进行了解释:
\n
\n[ 安装后自动删除 debs ]\n通过 apt(8) 成功安装软件包后,\n相应的 .deb 软件包文件将从 /var/cache/apt/archives 缓存目录中删除。\n[. ..]\n请注意,apt-get 的行为没有改变。下载的 deb\n安装后将保存在缓存目录中。\n
\n
-
-
BinaryCommandSpecificConfiguration(argv[0], CmdCalled)
两个二进制文件对所有这些命令执行相同的操作:"upgrade", "dist-upgrade", "full-upgrade"
。\n -
_config->MoveSubTree(conf.c_str(), nullptr)
根据使用的二进制文件应用以Binary::apt::apt
或Binary::apt::apt-get
为前缀的选项。\n
其他无关步骤省略。
然后,DispatchCommandLine
函数最终调用 DoDistUpgrade
处理程序。
稍后在调用堆栈中,DoCacheManipulationFromCommandLine()
行 681 中有一个有趣的部分:
bool const distUpgradeMode = strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0;
bool resolver_fail = false;
if (distUpgradeMode == true || UpgradeMode != APT::Upgrade::ALLOW_EVERYTHING)
resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode, &Progress);
同样,使用任一命令的两个二进制文件都执行相同的步骤。
也许我错过了一些东西,但这就是我要停止这项调查的地方。
第三种回答
使用 apt 作为首选,但如果您正在编写脚本,请使用 apt-get。 Apt-get 具有更稳定的输出(意味着输出格式尽可能保持不变,以免破坏自动解析该输出的脚本)。 Apt-get 还有一些 apt 中不可用的低级命令。
apt 和 apt-get 的手册页对 full-upgrade 和 dist-upgrade 的描述略有不同,但它们可能是相同的命令(apt 接受 dist-upgrade 作为 full-upgrade 的别名)。这是 apt-gets 稳定性的一个很好的例子。在 apt 中,名称被更改为更加用户友好,而在 apt-get 中,名称保持不变,以免破坏与旧脚本的兼容性。