如何重建损坏的dpkg状态文件?


26

每当我键入sudo apt-get remove然后按Tab自动完成键,我都会收到以下消息:

grep-status: /var/lib/dpkg/status:15945: expected a colon
.

在状态文件的第15945行,我看不到任何特别奇怪的东西。这是单声道库软件包的说明字段中的点字符,插入冒号没有帮助。删除包含点的线也不起作用。用过时的状态覆盖文件会产生相同的消息。

有什么方法可以重建状态文件?


3
我认为您无法完全重建status文件:它是信息的主要来源,尽管其中很多是多余的,但并非全部。但是,可能可以手动修复文件。发表周围有问题的行文件的块,说20-40线包括至少一个Package:之前和之后的一行行15945.
吉尔“SO-停止作恶”

此后,我尝试卸载mono,但所做的只是更改报告为错误的行号。如果您单击
拉蒙(Ramón)

@拉蒙所以apt-getdpkg朋友仍然能够正常工作,什么是示数出来是自动完成?
Riccardo Murri 2010年

正确。使用自动补全功能时,解析状态文件似乎只有问题。否则,我可以安装和删除软件包,而没有任何明显的错误。
拉蒙2010年

遇到同样的问题。我不认为盲目使用apt数据库的旧版本是正确的选择,无论它是否解决了问题。
奥利(Oli)

Answers:


7

我终于解决了这个问题。恢复状态文件的备份不起作用,因为我遇到了很长时间的问题,这是所有备份中的问题。

该修复程序包括grepping实际的格式中断并手动对其进行修复。它并不像听起来那样难。

http://thepcspy.com/read/fixing-dpkg-status-corruption/


很高兴您找到了解决方案,Oli,并感谢您的分享。在我的情况下,除了有问题的Lexmark deb之外,Webmin deb的描述也有误,但是在这种情况下,执行自动完成时不会引起任何解析问题。奇怪的。
拉蒙

3
@Oli您是许可证的持有人吗?你能在这里写吗?
Braiam 2013年

没错,我阅读了您的帖子。我有一个,missing package name然后我发现,出于某种奇怪的原因,我最好不要浪费时间去寻找,我有一条线Packaga: landscape-common在地形学上固定,而且很容易解决。问题是,我从未接触过此文件,也从未有人接触过。计算机如何弄乱拼写错误?
Severo Raz 2014年

实际的答案也应该在此处,以避免它是仅链接的答案[如果错误是由于出现在“ Package:”之前的空白行,则在.该空白行中添加a )。
Xen2050

20

您应该能够使用先前已知的良好状态文件并从那里进行更新。每次执行安装或更新时,状态文件都会保存到/ var / backups下的gzip 备份中。在目录上执行ls -l dpkg *显示:

-rw-r--r-- 1 root root   2266732 2010-09-30 08:35 dpkg.status.0
-rw-r--r-- 1 root root    624182 2010-09-29 08:49 dpkg.status.1.gz
-rw-r--r-- 1 root root    623844 2010-09-28 08:55 dpkg.status.2.gz
-rw-r--r-- 1 root root    620358 2010-09-24 11:04 dpkg.status.3.gz
-rw-r--r-- 1 root root    619021 2010-09-23 15:34 dpkg.status.4.gz
-rw-r--r-- 1 root root    619013 2010-09-23 08:03 dpkg.status.5.gz
-rw-r--r-- 1 root root    618968 2010-09-21 08:33 dpkg.status.6.gz

在/ var / lib / dpkg /目录中创建的文件的备份也名为status-old。在目录上执行ls -l status *显示:

-rw-r--r-- 1 root root 2266732 2010-09-30 08:35 status
-rw-r--r-- 1 root root 2267191 2010-09-30 08:35 status-old

因此,要从损坏中恢复,您应该能够执行以下操作:

1.备份损坏的状态文件

mv /var/lib/dpkg/status /var/lib/dpkg/status_bkup

2.从以上任一来源复制最新的dpkg状态文件:

要么

cp /var/lib/dpkg/status-old /var/lib/dpkg/status

要么

cp /var/backups/dpkg.status.#.gz /var/lib/dpkg/
gunzip -d /var/lib/dpkg/dpkg.status.#.gz 
mv /var/lib/dpkg/dpkg.status.# /var/lib/dpkg/status

3.然后运行apt-get update:

sudo apt-get update

那应该做。


2
我不知道/ var / backups中保存的状态文件。这是很好的信息,以防再次发生。谢谢,吉姆
拉蒙2010年

但是使用旧版本是否安全?我的意思是,当然不仅仅是使用此文件的自动完成功能,而且使用带有旧软件包信息的旧版本还会搞砸其他更重要的事情……例如apt本身。
奥利(Oli)

@Oli我不确定。我只需要这样做一次。我认为我必须重新安装导致问题的应用程序,但今后它仍然可以工作。与Internet上的所有建议(或者至少是我在Internet上的建议)一样,这对我很有用。这并不意味着它一定会为您工作。我提供的产品没有保修,也没有明确的了解它在系统上的性能。你的旅费可能会改变。请自担风险。
吉姆(Jim)2010年

此解决方案似乎已解决了我的问题。如果使用旧状态文件引起任何问题,我将进行更新。
马修

旧文件可能缺少对系统进行的某些软件包更改,但大多数情况下都可以。这样做sudo apt update && sudo apt dist-upgrade应该可以解决旧status文件可能导致的大多数问题。如果你的系统有一个更大的混乱,sudo aptitude dist-upgrade而不是sudo apt ...有时会提出更好的方法来修复破损。
Mikko Rantalainen

6

我可以通过删除状态文件中条目已损坏的软件包来解决此问题。

sudo dpkg -r handbrake-cli

通过pcregrep接受的解决方案不起作用(pcregrep找不到任何东西)。


非常感谢您,它对我
有用

6

对于有问题的软件包,请尝试使用“ dpkg -P”。它将从本地存储库中清除它,并删除所有跟踪。在我的系统上,这是修复了导致该错误的已删除(但尚未清除)软件包的修复程序。


5

在这种情况下,我将备份损坏的/var/lib/dpkg/status文件,然后使用来自以下位置的信息进行手动更正(在第1888和9550行附近)

apt-cache show libssl0.9.8
apt-cache show udev

知道了。apt-get现在运行平稳。
ændrük

3

这是一个Bug(应该已修复):Launchpad Bug 613018

上游:Debian Bug 590885

这应该是一种解决方法(备份,“修复”版本字符串):

cp /var/lib/dpkg/status ~/dpkg-status.back
sudo sed -i "s/56127_Ubuntu_karmic/56127Ubuntukarmic/" /var/lib/dpkg/status

2

的儿子...

好的,尽管实际错误发生在15266行,但据报道进一步下降了700行。状态文件中有问题的条目是由我安装的deb导致的,它使我的Lexmark打印机很久以前就可以工作了。该条目用于包装lexmark-inkjet-08-driver。“描述”字段没有.换行符。这导致了解析错误。

为了找到这一点,我采取了a弹枪故障排除方法,并开始随机地尝试一些事情。我的愚蠢尝试之一是grep-status -P e弄清楚e是字母表中最常见的字母。我知道是哑巴,但在它抱怨冒号冒号之前打印的最后状态记录是用于Lexmark软件包的,我注意到在.盯着屏幕看了几分钟后,缺少字符。

如果可能的话,我想再提出一个答案,它可以描述一种更好的方法来发现此类问题,以防将来有人遇到类似问题。谢谢。


grep-status -r -P ^应该始终与任何包匹配,因此它应该解析整个文件,如果无法解析,则中止。
Mikko Rantalainen

2

因为即使如此,我的老头子还是有问题apt-get update

这对我来说效果很好:

(作为根)

cd /var/lib/dpkg 

cp -avf status status.corrupt

tr -cd '\11\12\15\40-\176' < status.corrupt > status

此命令使用tr命令的-c和-d参数从输入流中除去除单引号之间显示的ASCII八进制值之外的所有字符。该命令专门允许以下字符通过此Unix过滤器:

八进制11:制表符

八进制12:换行

八月15:回车

八进制40到八进制176:所有“好”键盘字符

在翻译过程中,所有其他二进制字符(文件中的“垃圾”字符)都会被删除。

信用:http : //alvinalexander.com/blog/post/linux-unix/how-remove-non-printable-ascii-characters-file-unix

如果您想知道更改了什么,或损坏在哪里:(可能很长)

diff /var/lib/dpkg/{status-old,status} |less
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.