问题描述
我想将 /etc/
中的文件恢复为其 originally-installed 形式。自安装以来,我已经编辑了该文件。我怎样才能恢复这个配置文件? Apt 足够聪明,不会覆盖编辑过的配置文件,那么我如何告诉它我希望它这样做呢?
为了论证,假设我想从 foo
包中恢复文件 /etc/foo.conf
。
最佳思路
由 Ryan Thomson 提供的 The answer 正朝着正确的方向前进。它仍然无法完成这项工作(详细原因如下)。
正确(也是最简单)的方法是使用 -o
和 apt
来传递 dpkg 选项并强制 dpkg
询问您是要保留修改后的配置文件还是原始配置文件。命令将是这样的 –
sudo apt-get --reinstall -o Dpkg::Options::="--force-confask" install foo
这会问你一个类似的问题
Configuration file '/etc/foo/foo.conf'
==> Modified (by you or by a script) since installation.
Version in package is the same as at last installation.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer's version
N or O : keep your currently-installed version
D : show the differences between the versions
Z : start a shell to examine the situation
The default action is to keep your current version.
*** foo.conf (Y/I/N/O/D/Z) [default=N] ?
您必须按 Y 或 I 才能安装包维护者的原始配置文件。您甚至可以按 D 查看更改或使用 Z 选项启动 root shell 来修复自己。
注意:替换后,您会发现修改后的文件为 at /etc/foo/foo.conf.dpkg-old
为什么其他选项不起作用?
因为 dpkg 中的其他选项效果不佳。处理包的配置文件的选项是
-
--force-confmiss
-
--force-confnew
-
--force-confold
-
--force-confdef
--force-confmiss
在包版本不变时不起作用。从 man-page
If a conffile has been modified and the version in the package did change, always install the new version without prompting, unless the –force-confdef is also specified, in which case the default action is preferred.
--force-confmiss
适用于缺少的配置文件。当版本没有改变时,它也会失败。引用 man-page
confmiss: If a conffile is missing and the version in the package did change, always install the missing conffile without prompting. This is dangerous, since it means not preserving a change (removing) made to the file
--force-confold
只有在版本发生变化时才会保留修改后的版本。对于同一个包,它也会失败。引用 man-page
confold: If a conffile has been modified and the version in the package did change, always keep the old version without prompting, unless the –force-confdef is also specified, in which case the default action is preferred.
--force-confdef
也将失败,因为默认操作是保留旧文件(从 --force-confask
显示的消息中指示。它有 (Y/I/N/O/D/Z) [default=N]
行,这意味着保留是默认值。见上文)。如果指定了 --force-confnew
但版本没有改变,那也不起作用。引用 man-page
confdef: If a conffile has been modified and the version in the package did change, always choose the default action without prompting. If there is no default action it will stop to ask the user unless –force-confnew or –force-confold is also been given, in which case it will use that to decide the final action.
只有 --force-confask
可以工作,因为即使版本相同,它也会明确地问你这个问题。引用 man-page
confask: If a conffile has been modified always offer to replace it with the version in the package, even if the version in the package did not change (since dpkg 1.15.8). If any of –force-confmiss, –force-confnew, –force-confold, or –force-confdef is also given, it will be used to decide the final action.
希望这会有所帮助。
次佳思路
如果危害已经造成,这里有一个命令行方式获取配置文件的正式版本。首先,下载包文件(使用 apt-get --download-only
如下,或从 packages.ubuntu.com 上的包页面),然后在临时位置提取其内容。然后,您可以将该文件复制到 /etc
中。确保尊重原始权限(/etc
中的大多数文件由 root 和模式 644(即 word-readable 和 root-writable)拥有,但每个例外都有一个重要原因)。
sudo apt-get --download-only --reinstall install foo
mkdir /tmp/foo
dpkg-deb -x /var/cache/apt/archives/foo_VERSION_ARCH.deb /tmp/foo
请注意,这不适用于不是来自包的配置文件,例如 /etc/fstab
或 /etc/passwd
。如果你失去了这些,你就靠自己了。 (无论如何,大多数都是非常 system-dependent。)
对于未来,我建议使用 etckeeper 。安装包并运行 sudo etckeeper init
。这将为 /etc
中的所有文件设置版本控制。你不需要做任何其他事情来管理 etckeeper;你只需要在你想做版本控制操作时才需要和它交互,比如引用旧文件。每次运行 apt 之前和之后,每晚都会自动提交文件(这是可配置的)。
默认情况下,在 Ubuntu 上,etckeeper 使用 Bazaar 。如果您更喜欢 Darcs、Git 或 Mercury,请在运行 etckeeper init
之前更改 /etc/etckeeper/etckeeper.conf
中的设置。
使用 Bazaar,将 /etc/foo.conf
恢复到最后提交的版本:
cd /etc
sudo bzr revert foo.conf
如果您想回到更远的时间,请使用 sudo bzr log foo.conf
查看文件的历史记录,如果您确定 revno: 42
是您要恢复到的修订,请使用 sudo bzr revert -r 42 foo.conf
。
第三种思路
您可以从 packages.ubuntu.com 手动下载软件包,解压缩文件并用它替换您的版本。
或者你可以:
sudo rm /etc/foo.conf # just for good measure
sudo apt-get --purge --reinstall install foo
第二个感觉更野蛮。如果它使用多个文件,它也可能会清除其他配置。第一个是更多的点击和努力,但它似乎更安全。
第二,您可以删除该文件,而 –reinstall 可能会替换它。如果是这样,那就更安全了。