通过脚本添加 ppa 的最优雅方式

通过脚本添加 ppa 的最优雅方式

我正在编写一个可以自动添加 PPA 的 bash 脚本。问题是,如果您只运行 add-apt-repository ppa 命令,那么在运行同一脚本几次后,您将在 /etc/apt/sources.list.d 文件夹中的每个 PPA 列表文件中得到一堆重复的注释行。

解决这个问题的一个方法是按照此问题/答案中所述,在添加之前进行检查。

我对该答案中的大块代码感到有点反感。如果我们先将它们添加,然后再清理文件,会怎么样?看起来会像这样:

sudo apt-add-repository -y ppa:rael-gc/rvm

# remove the duplicate ppa in the files
ls /etc/apt/sources.list.d/*.list |  xargs -n 1 -I {} sh -c "uniq {} | sudo tee {}"

上述方法有什么缺点吗? 有什么潜在的危险问题吗?


apt-add-repository 执行此操作的示例:

cat /etc/apt/sources.list.d/rael-gc-ubuntu-rvm-xenial.list
deb http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main
# deb-src http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main

sudo apt-add-repository -y ppa:rael-gc/rvm

cat /etc/apt/sources.list.d/rael-gc-ubuntu-rvm-xenial.list
deb http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main
# deb-src http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main
# deb-src http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main

答案1

这不完全是代码审查但我们还是开始了。

不要解析 的输出ls

ls /etc/apt/sources.list.d/*.list | xargs ...

请不要这样做。请参阅章节标题中的链接,了解原因和可能的替代方案。这里最简单、最优雅的解决方案是使用 shell 通配符来生成要在 for 循环中迭代的项目:

for l in /etc/apt/sources.list.d/*.list; do
    uniq "$l" | sudo tee "$l"
done

就地转换文件

我们都知道,用一个程序读取文件并将输出重定向回同一个文件可能会导致文件为空。tee介于两者之间会有所帮助,因为它会缓冲输入一段时间,直到将其写入输出,但这是一个实现细节,可能会因不同的tee实现和/或不同的内核而失败。一旦输出的大小超过缓冲区的大小,它也会失败。相反,你应该使用类似

uniq "$l" | sudo sponge "$l"

或者可能

sudo sed -i ... "$l"

如果您能找到合适的 sed 脚本来完成这项工作。

两者都有额外的好处,即它们不会将输入写入标准输出,但>/dev/null无论如何你都可以抑制这一点。

uniq真的找到重复的 Apt 源代码行吗?

看着sources.list(5),Apt 源代码行可以包含多个“组件”。以下源文件等效但不完全相同:

  • 单、多组分生产线:

    deb http://de.archive.ubuntu.com/ubuntu/ trusty-security main restricted
    
  • 多条单组分生产线:

    deb http://de.archive.ubuntu.com/ubuntu/ trusty-security main
    deb http://de.archive.ubuntu.com/ubuntu/ trusty-security restricted
    

显然,因此uniq无法找到所有重复的 Apt 源代码行。但是,由于 上的存储库ppa.launchpad.net不支持多个组件,因此如果您仅使用该站点的 PPA,则可能会顺利进行。此外,重复项可能分布在多个文件中,除非您依赖于 以add-apt-repository某种智能方式管理源文件并在每个文件中只放置一个 PPA,否则这种方法将完全失效。

虽然可以编写一个 Bash 程序,在检查重复项时考虑多组件行,但最好使用现有的软件库来解析 Apt 源代码行,而不是自己动手解决。Pythonaptsources的模块(打包在python-apt或 中python3-apt)就是这样一个库。您可以在 中找到其使用示例apt-remove-duplicate-source-entries(源自问题我怎样才能自动修复“W:目标包...”被多次配置?)。

相关内容