Mar*_*ino 3 bash sed unattended-upgrades text-processing
我最近开始在一家全 Linux 公司担任 IT 人员,并注意到我们所做的一些任务可以“轻松”自动化。今天的自动化任务是/etc/apt/apt.config.d/50unattended-upgrades在新计算机上安装软件和配置。我已经编写了软件安装脚本,但现在我一直坚持取消注释所需的无人值守升级行。
我给你举个例子,这个:
// Automatically upgrade packages from these (origin:archive) pairs
//
// Note that in Ubuntu security updates may pull in new dependencies
// from non-security sources (e.g. chromium). By allowing the release
// pocket these get automatically pulled in.
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
// Extended Security Maintenance; doesn't necessarily exist for
// every release and this system may not have it installed, but if
// available, the policy for updates is such that unattended-upgrades
// should also install from here by default.
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
Run Code Online (Sandbox Code Playgroud)
应该看起来像这样:
// Automatically upgrade packages from these (origin:archive) pairs
//
// Note that in Ubuntu security updates may pull in new dependencies
// from non-security sources (e.g. chromium). By allowing the release
// pocket these get automatically pulled in.
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
// Extended Security Maintenance; doesn't necessarily exist for
// every release and this system may not have it installed, but if
// available, the policy for updates is such that unattended-upgrades
// should also install from here by default.
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
"${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
Run Code Online (Sandbox Code Playgroud)
(更新行应该取消注释)
我尝试用 sed 来做到这一点,但它不起作用,可能是因为我完全是个菜鸟。这是我笨拙的 sed 行,希望有人可以向我解释我做错了什么!
#!/bin/bash
sudo sed -i 's@// "${distro_id}:${distro_codename}-updates"@ "${distro_id}:${distro_codename}-updates"@' /etc/apt/apt.conf.d/50unattended-upgrades
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激!祝你今天过得愉快!
为什么不直接创建另一个/etc/apt/apt.config.d/51my-unattended-upgrades包含以下内容的文件:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-updates";
};
Run Code Online (Sandbox Code Playgroud)
选项合并在一起。用 来检查apt-config dump。
此外,只需删除单个文件即可更轻松地删除更改。并且任何升级更改都/etc/apt/apt.conf.d/50unattended-upgrades不会破坏您的更改。
如果不需要,最好不要更改其他人的配置文件。
尝试解释一下:
从 python 源代码unattended-upgrade中您可以看到,它不会解析/etc/apt/.... 相反,它使用 python-apt-api。apt-config它类似于在 shell 中使用(您应该始终这样做,而不是读取配置文件)。
在这种特殊情况下,python-apt-api 会合并所有文件并返回一个列表,Origins-Pattern并且unattended-upgrade脚本会循环遍历所有文件。
我不知道有什么关于这方面的好的文档。你能做的最好的事情就是调查来源。
请参阅Marco的回答,这是正确的方法\xc2\xae,我sed在这里只关注 和 正则表达式问题。
使用正则表达式的第一条规则是“少即是多”。不要尝试匹配整行,而是使用尽可能小的正则表达式来捕获您需要捕获的内容。例如,在这里,您不关心行开头的空格,因此不必费心尝试匹配它们。另外,空格的数量很可能会改变,你不希望它破坏你的脚本,所以忽略它们!
\n据我所知,您真正要做的就是//从包含字符串的任何行中删除前导-updates。如果是这样,您所需要的只是:
sed \'/-updates/{s@^\\s*//@@}\' /etc/apt/apt.conf.d/50unattended-upgrades\nRun Code Online (Sandbox Code Playgroud)\n这意味着“如果此行匹配-updates,则替换 0 个或多个前导空白字符(注释不必是该行的第一个字符),后面//什么都没有”。//因此,这将从匹配的行中删除前导-updates。
正如您所看到的,这更容易编写和理解。也就是说,您的原始命令按照示例文件的预期工作,只是不必要地复杂和脆弱(如果添加空格,它就会中断):
\n$ sed \'s@// "${distro_id}:${distro_codename}-updates"@ "${distro_id}:${distro_codename}-updates"@\' file \n/ Automatically upgrade packages from these (origin:archive) pairs\n//\n// Note that in Ubuntu security updates may pull in new dependencies\n// from non-security sources (e.g. chromium). By allowing the release\n// pocket these get automatically pulled in.\nUnattended-Upgrade::Allowed-Origins {\n "${distro_id}:${distro_codename}";\n "${distro_id}:${distro_codename}-security";\n // Extended Security Maintenance; doesn\'t necessarily exist for\n // every release and this system may not have it installed, but if\n // available, the policy for updates is such that unattended-upgrades\n // should also install from here by default.\n "${distro_id}ESMApps:${distro_codename}-apps-security";\n "${distro_id}ESM:${distro_codename}-infra-security";\n "${distro_id}:${distro_codename}-updates"; \n// "${distro_id}:${distro_codename}-proposed";\n// "${distro_id}:${distro_codename}-backports";\n};\nRun Code Online (Sandbox Code Playgroud)\n最后,一些一般性观察:
\nsed -i在未进行备份的情况下使用该-i选项允许您指定备份后缀,因此如果您运行sed -i.bak \'s/a/b/\' file,则会将原始文件复制为file.bak. 所以你应该做一些像sudo sed -i.bak ...你的情况一样的事情,这样你就可以随时撤消事情。sudo其放入脚本中很少是一个好主意。相反,编写 without 脚本sudo,然后使用 with 调用sudo它sudo script.sh。