/etc/apt/sources.list.d相对于/etc/apt/sources.list有什么好处?


14

我知道以前曾问过这个问题,但我不接受“您可以清楚地看到自定义添加项”的答案。当我添加ppa时(这是我多年以来未曾做过的事情),我敲了键盘上标有“ Enter”的键,这使我可以在新条目之前添加一个空行(我什至会添加一个解释性注释,但我是技术作家,所以.....)。我喜欢sources.conf干净整洁。

/etc/apt/sources.d

意味着我有六个要解析的文件,而不是一个。

AFAIK,拥有一个配置文件与6没有“绝对”优势(出于争辩,也许您拥有3甚至2,没关系……1仍然胜过2)。

有人可以拿出一个理性的优势,“您可以清楚地看到自定义添加项”是一个穷人的借口。

我必须补充一点,我爱改变,但是,只有在改变带来了好处的情况下,我才喜欢。

首次回复后进行编辑:

它允许需要自己存储库的新安装不必搜索平面文件以确保它没有添加重复的条目。

现在,他们必须在目录中搜索重复文件而不是平面文件。除非他们假设管理员不要改变事情...

它使系统管理员可以轻松地禁用(通过重命名)或删除(通过删除)存储库集,而无需编辑整体文件。

管理员必须在grep目录下找到合适的文件进行重命名,然后他才可以搜索一个文件并注释掉一行,而sed单行代码几乎“可以”管理任何管理员。

它允许程序包维护人员发出简单的命令来更新存储库位置,而不必担心无意间更改了无关存储库的配置。

我不明白这一点,我“假设”包维护者知道他的存储库的URL。同样,必须sed具有目录而不是单个文件。


2
评论和问题编辑已从“试图回答问题”迅速转变为“对问题的存在的保证”。有用的评论已经出现在接受的答案中
Michael Mrozek

Answers:


14

从技术上讲,由于不得不使用一些大型且流行的系统信息工具来应对这些更改的人员,基本上可以归结为:

对于sources.list.d /

# to add
if [[ ! -e /etc/apt/sources.list.d/some_repo.list ]];then
  echo 'some repo line for apt' > /etc/apt/sources.list.d/some_repo.list
fi

# to delete
if [[ -e /etc/apt/sources.list.d/some_repo.list ]];then
  rm -f /etc/apt/sources.list.d/some_repo.list
fi

请注意,除非他们也进行以下相同的检查,否则如果您注释了一个回购行,则这些测试将是错误的。如果他们执行以下相同的检查,则除了要对许多文件执行而不是对一个文件执行之外,它的精确度也相同。另外,除非他们正在检查所有可能的文件,否则他们可以并且经常这样做,添加重复项,这会引起抱怨,直到删除其中一个为止。

对于sources.list

# to add. Respect commented out lines. Bonus points for uncommenting
# line instead of adding a new line
if [[ -z $( grep -E '\s*[^#]\s*some repo line for apt' /etc/apt/sources.list ) ]];then
  echo 'some repo line for apt' >> /etc/apt/sources.list
fi

# to delete. Delete whether commented out or not. Bonus for not
# deleting if commented out, thus respecting the user's wishes
sed -i '/.*some repo line for apt.*/d' /etc/apt/sources.list

Google Chrome开发人员没有检查是否存在Google Chrome来源,而是依赖于他们的Chrome软件包创建的确切文件名。在所有其他情况下,他们将在sources.list.d中创建一个新文件,并以他们想要的方式命名。

当然,要了解您拥有哪些资源,并不是那么容易,因为您比以下任何人都更容易阅读和维护:

cat /etc/sources.list

因此,就我所知,这样做基本上是出于自动更新的目的,并提供了可以提供给用户的简单命令。对于用户而言,这意味着他们必须读取许多文件而不是1个文件才能查看是否已添加回购协议;对于apt而言,这意味着它还必须读取许多文件而不是一个文件。

由于在现实世界中,如果要做好这些工作,就必须支持对所有文件的检查,无论它们的名称是什么,然后测试是否需要执行操作。

但是,如果您做得不好,则只需忽略检查以查看该项目是否在源代码中的某个位置,然后检查文件名即可。我相信这是大多数自动化工具所做的事情,但是从最后开始,我只需要检查所有内容,就可以列出所有文件并根据其中一个文件是否匹配进行操作,唯一的实际结果就是使其变得更加复杂。

批量修改

考虑到运行了许多服务器,我很想编写一份夜间工作脚本,该工作遍历/etc/apt/sources.list.d/并首先检查以确保该项目不在source.list中,然后检查是否存在不,将其添加到sources.list,删除sources.list.d文件,如果已经在sources.list中,则只需删除sources.list.d文件

由于仅使用source.list不会带来任何负面影响,而且不仅简单而且易于维护,因此添加类似的内容可能不是一个坏主意,尤其是在系统管理员做出创造性随机操作的情况下。

如上面的注释所述,inxi -r将为每个文件整齐地打印出活动的仓库,但是当然不会编辑或更改它们,因此仅是解决方案的一半。如果有很多分布,那肯定是学习每个方法的痛苦,这是肯定的,随机性当然是规则而不是例外。


评论不作进一步讨论;此对话已转移至聊天
terdon

38

将每个存储库(或存储库集合)都保存在自己的文件中,使手动和程序管理变得更简单:

  • 它允许需要自己存储库的新安装不必搜索平面文件以确保它没有添加重复的条目。
  • 它使系统管理员可以轻松地禁用(通过重命名)或删除(通过删除)存储库集,而无需编辑整体文件。
  • 它允许程序包维护人员发出简单的命令来更新存储库位置,而不必担心无意间更改了无关存储库的配置。

11
这比公认的答案要好。关键概念是“所有权”。该.d设计明确分离由不同的实体所拥有的配置状态。一个包可能归一个包所有。可以通过安装另一个wget ...。对于单个怪物文件,任何自动化或半自动化过程如何“知道”它拥有配置的哪一部分?事实并非如此,这就是.d设计出众的原因。
Nemo

12
不确定“手工”,但是我已经好多年没有这样做了。它有利于程序化管理。使用像Puppet这样的配置管理软件时,只需要删除dir中的文件或删除文件并运行apt update,而不是解析文件来添加或删除行,就会更容易。特别是因为这样避免了必须管理来自多个独立模块的单个“文件”资源。由于这个原因,我感谢Ubuntu广泛使用“ .d”目录。
马丁·海姆斯

2
@MartijnHeemels如果可以的话,我将对您的评论进行一百次投票。对我个人而言,.d一旦我开始进行繁重的Puppet / Salt配置管理,设计的优势就会立即成为关注焦点。
smitelli

3
@thecarpy,如果您的管理员试图欺骗您,您应该找到更多值得信赖的管理员。称我(或确实任何人)写的“垃圾”充其量是不礼貌的。
DopeGhoti

7
从操作观点确认这一点。由特定程序包或配置管理系统的模块配置和拥有整个文件比尝试为配置的每个应用程序动态编写解析器要干净得多。仅仅为了apt似乎微不足道,但是随后您得到了许多可以使用相同策略的其他系统(logrotate,cron,sysctl,sudoers,rsyslog,modprobe,...从service.d/*文件加载配置)部署文件而不是修改现有文件也更适合图像缓存/比较。
维普托

10

如果您要手动管理服务器,我会同意,这会使事情更加混乱。但是,它有利于程序化管理(即“配置为代码”)。使用Puppet,Ansible,Chef等配置管理软件时,只需删除或删除dir中的文件并运行apt update,而不是解析文件来添加或删除某些行,就会更容易。

特别是因为这样避免了必须/etc/apt/sources.list从第三方编写的多个独立模块中管理单个'文件'资源的内容,例如:。

出于这个特殊原因,我感谢Ubuntu广泛使用“ .d”目录,例如sudoers.d,rsyslog.d,sysctl.d。,cron.d,logrotate.d等。


5

正如nemo在评论中指出的那样,目录的主要优点之一是它允许“所有权”的概念。

现代Linux发行版和安装程序都基于软件包的思想- 软件包的独立部分,可以尽可能地原子地添加和删除。每当您使用dpkg(并因此apt)安装软件包时,它都会跟踪该安装程序在系统上创建了哪些文件。然后,卸载软件包可能主要包括删除这些文件。

目前接受的答案将其作为一件坏事,一个谷歌浏览器的安装程序认为它应该只创建或删除其预期位置的条目,但自动化别的导致各种可怕的边缘情况; 例如:

  • 如果sources.list安装时该行存在,但已被注释掉,则安装程序应取消注释,还是添加重复项?
  • 如果卸载程序删除了该行,但用户已在其旁边添加或编辑了注释,则该文件将留下不完整的注释。
  • 如果用户手动添加了该行,则安装程序会知道不添加它;但是卸载程序如何知道不删除它?

所有权不需要单独的文件;例如,安装程序可以包含一段注释,说明其“拥有”一组特定的行。在这种情况下,它将始终在文件中搜索该确切的块,而不是在其他地方提及同一存储库。

在其他条件相同的情况下,自动编辑单个配置文件比自动创建和删除单独的文件要复杂得多。至少,删除线条需要使用某些模式匹配工具,例如sed。在更复杂的文件中,添加和删除行都可能需要具有文件格式知识的脚本工具才能添加到适当的部分,或者在不损害周围格式的情况下进行删除。

由于安装程序无论如何都需要避免与手动编辑的配置混淆,因此以易于自动化工具管理的格式放置工具拥有的自动化配置是有意义的。


3

这允许程序包添加额外的资源,而无需借助脚本。

例如,当您安装Microsoft的Skype软件包时,会自动将skype.com的源配置为下载更新。从系统中删除Skype软件包还会再次禁用此软件包源。

如果您希望对平面文件具有相同的效果,则Skype的安装脚本将需要修改您的sources.list,这可能会使许多系统管理员感到有些不安。


-3

我不相信有一个很好的理由-除了看起来很时髦以外。对我来说,这违反了一个规则,即目录应该是叶或节点-即它应仅包含文件或目录,而不是两者的混合。

我猜想它确实使文件更小,更易于阅读-例如对于sudo规则(可能会很长),它确实使针对一种类型的用户的一组标准化规则变得更加容易(例如,开发人员),然后将其添加到config目录中(如果应允许在此计算机上对devs进行sudo的话);因此,您需要维护的文件更少-仅是供开发人员,管理员,sysop等使用的文件,而不是每种可能的组合。

在那里,我自相矛盾。


3
我不会将“目录应该是叶还是节点”作为规则。作为一个人为的示例,请看/var/log。一个简单的守护程序可以直接在内部写入一个唯一的文件:/var/log/simple.log。更复杂的后台程序可能需要它自己的子目录:/var/log/complex/a.log/var/log/complex/b.log/var/log/complex/c.log...类似的模式与CONFIGS。
smitelli

我希望将其设置为/var/log/simple/log.1 .2等,该路径为您提供信息。SO var log将包含每种日志类型的子目录,并且每个子目录中可以包含一个或多个文件。我承认,有些例子中的例外是合理的,但作为一般规则,这是很好的。我讨厌看到带有文件的主目录-证据,混乱的IMO。
Graham Nicholls

3
这里一个很好的理由,但你需要你了解它之前所想的那么管理员。请参阅DopeGhoti的答案。
reinierpost

好吧,那把我放在了我的位置上,不是吗? 显然,我不能以管理员身份考虑-或我只是不同意您的意见。
格雷厄姆·尼科尔斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.