损坏的 dpkg 状态文件

损坏的 dpkg 状态文件

上周升级系统后,S 变得很差劲。浏览了论坛,但没有找到解决问题的答案。DPKG 中的“状态”文件已损坏,备份为空,因此尝试使用以下方法恢复:

(for d in /usr/share/doc/* ; do printf 'Package: %s\nStatus: install ok installed\n' $(basename $d) ; done ) > ~/status
cp ~/status /var/lib/dpkg/

我的安装:

虚拟服务器,操作系统模板 ubuntu-12.04-x86_64 + 带有邮件和网站的 Plesk 客户端服务器

正如恢复状态文件后我运行的那样:

root@justme:~# sudo apt-get dist-upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following NEW packages will be installed:
  adduser apt-utils base-files base-passwd bash bash-completion bsdmainutils bsdutils busybox-initramfs coreutils cpio cryptsetup cryptsetup-bin dash dbus debconf-i18n debianutils diffutils
  dmsetup dpkg e2fslibs e2fsprogs ecryptfs-utils file findutils gcc-4.6-base gettext-base grep gzip hostname ifupdown initramfs-tools initramfs-tools-bin initscripts insserv iproute keyutils
  klibc-utils libacl1 libapt-inst1.4 libapt-pkg4.12 libatm1 libattr1 libblkid1 libbz2-1.0 libc-bin libc6 libcomerr2 libcryptsetup4 libdb5.1 libdbus-1-3 libdevmapper1.02.1 libdrm-intel1
  libdrm-nouveau1a libdrm-radeon1 libdrm2 libecryptfs0 libexpat1 libffi6 libgcc1 libgcrypt11 libglib2.0-0 libglib2.0-data libgpg-error0 libgpm2 libkeyutils1 libklibc liblocale-gettext-perl
  liblzma5 libmagic1 libmount1 libncurses5 libncursesw5 libnih-dbus1 libnih1 libnspr4 libnss3 libnss3-1d libpam-modules libpam-modules-bin libpam-runtime libpam0g libpciaccess0 libpcre3
  libplymouth2 libpng12-0 libpopt0 libreadline6 libselinux1 libslang2 libsqlite3-0 libss2 libssl1.0.0 libstdc++6 libtext-charwidth-perl libtext-iconv-perl libtext-wrapi18n-perl libtinfo5 libudev0
  libuuid1 libxml2 login lsb-base lsof makedev mime-support module-init-tools mount mountall multiarch-support ncurses-base ncurses-bin netbase original-awk passwd perl-base plymouth
  plymouth-theme-ubuntu-text procps psmisc python python-minimal python2.7 python2.7-minimal readline-common rsync sed sensible-utils sgml-base shared-mime-info sysv-rc sysvinit-utils tar tzdata
  udev upstart util-linux uuid-runtime xml-core xz-utils zlib1g
The following packages will be upgraded:
  debconf
1 upgraded, 141 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/38.3 MB of archives.
After this operation, 118 MB of additional disk space will be used.
Do you want to continue [Y/n]? y
Extracting templates from packages: 100%
Preconfiguring packages ...
dpkg-query: error: parsing file '/var/lib/dpkg/status' near line 15 package 'acl:i386':
 blank line in value of field 'Original-Maintainer'
' not allowed (only letters, digits and characters `-+._')install-info
E: Sub-process /usr/bin/dpkg returned an error code (2)
W: Encountered status field in a non-version description

有人可以帮忙吗?几乎到处都找过了。

答案1

这肯定是一个 Bug。

按顺序尝试以下操作,直到问题得到解决。

sudo dpkg --configure -a
sudo apt-get dist-upgrade

如果失败,请尝试

sudo rm /var/lib/dpkg/available
sudo dselect update
sudo apt-get dist-upgrade

或者如果一切都失败了

sudo rm /var/lib/dpkg/{status,available}
sudo apt-get update
sudo apt-get dist-upgrade

如果失败,您将需要编辑文件并删除有问题的行或提交错误报告。

答案2

我遇到了同样的问题 E:子进程 /usr/bin/dpkg 返回错误代码 (2) W:在非版本描述中遇到状态字段

我用 status_old 文件替换了 dpkg 状态文件。它解决了我的问题。/var/lib/dpkg/status

答案3

我的/var/lib/dpkg/status文件被删除了,根据 apt 的说法,我没有安装任何软件包,因为它是根据文件来确定的status。我使用以下方法重新生成/var/lib/dpkg/status文件。这种方法在基于 Debian 的 Kali GNU/Linux 中对我来说非常有效。

笔记:

  • 此方法假定所有已安装的包都已在/usr/share/doc目录中创建条目。

  • 此方法从一个空/var/lib/dpkg/status文件开始。

  • 如果您有多个存储库提供相同的软件包,则此方法可能不起作用。如果您有多个存储库提供相同的软件包,请暂时禁用子存储库,然后删除 中的存储库的软件包缓存列表/var/lib/apt/lists/

  1. 删除当前status文件status-old。删除前请备份文件,以防出现错误。

    mkdir ~/dpkg-status-backup
    cp /var/lib/dpkg/{status,status-old} ~/dpkg-status-backup
    rm /var/lib/dpkg/{status,status-old}
    
  2. 获取已安装的所有软件包的列表,每行一个软件包。注意:是1(一) 而不是l(小写的 L)。

    ls -1 /usr/share/doc > installed-packages.list
    
  3. 将包列表重写为一行。

    tr '\n' ' ' < installed-packages.list > installed-packages-one-line.list
    
  4. 创建一个空status文件以使 apt-cache 能够运行。

    touch /var/lib/dpkg/status
    
  5. 使用 apt-cache 生成包记录。

    cat installed-packages-one-line.list | xargs apt-cache show > raw-status-file
    
  6. 可能raw-status-file包含Status:某些包的字段。请删除它们以避免重复。

    sed -i '/^Status:/d' raw-status-file
    
  7. 为每个包添加Status:字段以向 apt 和 dpkg 指示它们已安装。

    sed -i 's/^Package:.*/&\nStatus: install ok installed/' raw-status-file
    
  8. status删除文件:SHA1:SHA256:MD5sum:Description-md5:Size:&中 dpkg 不需要的字段Filename:

    sed -i '/^MD5sum:/d' raw-status-file
    sed -i '/^SHA1:/d' raw-status-file
    sed -i '/^SHA256:/d' raw-status-file
    sed -i '/^Size:/d' raw-status-file
    sed -i '/^Filename:/d' raw-status-file
    sed -i '/^Description-md5:/d' raw-status-file
    
  9. raw-status-file运行上述命令后的结果现在是实际的 dpkgstatus文件。

    mv raw-status-file status
    
  10. 将文件复制status/var/lib/dpkg/asstatus和 status-old

    cp status /var/lib/dpkg/status
    cp status /var/lib/dpkg/status-old
    
  11. 现在运行 dpkg 来验证您的新状态文件。如果出现错误,请从 dpkg 的错误报告中获取提示并进行相应解决。如果没有出现错误,则文件status具有正确的语法。

    dpkg --get-selections
    
  12. 重新启用已禁用的 repos,然后运行 ​​apt 来更新包缓存列表,以防止出现错误packages have unmet dependencies

    apt update
    
  13. 如果您在 apt 中遇到packages have unmet dependencies错误,请确保您已启用提供依赖项的附属存储库,然后运行 ​​aptitude。我更喜欢它,aptitude因为它更擅长解决软件包安装错误。

    aptitude full-upgrade
    

如果你没有收到任何错误或你的错误已经从 apt 或 dpkg 中解决,并且得到“包裹已经是最新版本...”当您尝试安装一个您确定已经安装的程序时,例如coreutils,那么您就成功重新生成了 dpkgstatus文件。

清理创建的临时文件和备份。

rm installed-packages.list installed-packages-one-line.list status
rm -r ~/dpkg-status-backup

相关内容