Найдите (и переустановите), пакеты с поврежденными файлами (ничего не повреждая)

Я обычно предпочитаю фиксировать систему Linux, чем переустановить с нуля. Мои компьютеры видели много обновлений распределения и список PPAs или сторонних репозиториев. APT обычно удостоверяется, что все работает в конце. Однако то, что диспетчер пакетов думает, что все необходимые пакеты 'установлены', не гарантирует, что все файлы присутствуют в файловой системе.

Такая такая ситуация может произойти, если Вы имеете к проблемам зависимости обходного решения с dpkg --force-*. Можно было также воспроизвести такую ситуацию путем удаления файла из /usr как корень.

Существует ли простой способ проверить, присутствуют ли все файлы, принадлежащие установленному пакету?

Если такой проблемный пакет найден, aptitude reinstall решает проблему.

42
задан 8 April 2014 в 05:46

5 ответов

Ответ на вопрос был получен в другом месте:

Есть ли проверка на вменяемость Ubuntu?: debsum пакета может вычислять MD5 хэши и сравнивать их с deb пакетом.

Есть ли безопасный способ переустановки с помощью менеджера пакетов: Да, но не рекомендуется.

4
ответ дан 23 November 2019 в 00:25

Использование программы dpkg вместе с некоторым Bash скриптингом должно помочь вам в этом. Единственное предостережение будет, если кто-то заменит "чистые" версии файлов на "вредоносные". Для этого вам нужно будет получить правильные контрольные суммы MD5 из чистого пакета. В любом случае, вот код оболочки для достижения того, что вы хотите:

#!/bin/sh
PACKAGE_NAME="xterm"
for i in `sudo dpkg -L ${PACKAGE_NAME}`
do
    if ! [ -e $i ]; then
            echo "$i is a missing file in the $PACKAGE_NAME package."
    fi
done

Скрипт будет распечатывать только в том случае, если файл или каталог, который был определен в пакете, отсутствует. Также вам нужно будет заменить переменную 'PACKAGE_NAME' на пакет, который вы хотите проверить. Надеюсь, это поможет.

-1
ответ дан 23 November 2019 в 00:25

Из man-страницы debsums:

apt-get install --reinstall $(dpkg -S $(debsums -c) | cut -d : -f 1 | sort -u)
       Reinstalls packages with changed files.

Я просто запустил это в своей системе, потому что содержимое диска было случайно повреждено во время экспериментов с бета-версией операционной системы. Вот что я сделал (и, похоже, это сработало хорошо):

Во-первых, я установил "debsums" и запустил их, чтобы посмотреть, есть ли у меня повреждённые файлы в системе:

$ sudo apt-get install debsums
$ sudo debsums_init
$ sudo debsums -cs
/usr/share/bash-completion/completions/ssh
/usr/share/icons/hicolor/scalable/actions/cheese-take-photo.svg
/usr/share/gnome/help/gnumeric/C/files-textopen.xml
/usr/share/dbus-1/services/indicator-sound.service
/lib/modules/3.11.0-12-generic/kernel/drivers/mtd/ubi/ubi.ko

Как вы видите, у меня есть пять повреждённых файлов, так что мне нужно переустановить их. Вот как я нашел, какие пакеты содержат поврежденные файлы:

$ sudo debsums -c | xargs -rd '\n' -- dpkg -S | cut -d : -f 1 | sort -u
bash-completion
cheese-common
gnumeric-doc
indicator-sound
linux-image-extra-3.11.0-12-generic

Затем я исправил повреждение, переустановив поврежденные пакеты:

$ xargs -rd '\n' -a <(sudo debsums -c | xargs -rd '\n' -- dpkg -S | cut -d : -f 1 | sort -u) -- sudo apt-get install -f --reinstall --
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following package was automatically installed and is no longer required:
  linux-image-generic
Use 'apt-get autoremove' to remove it.
0 upgraded, 0 newly installed, 5 reinstalled, 0 to remove and 0 not upgraded.
Need to get 43.9 MB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 http://us.archive.ubuntu.com/ubuntu/ saucy/main bash-completion all 1:2.0-1ubuntu3 [173 kB]
Get:2 http://us.archive.ubuntu.com/ubuntu/ saucy/main cheese-common all 3.8.3-0ubuntu1 [2,929 kB]
Get:3 http://us.archive.ubuntu.com/ubuntu/ saucy/universe gnumeric-doc all 1.12.6-1 [7,295 kB]     
Get:4 http://us.archive.ubuntu.com/ubuntu/ saucy/main linux-image-extra-3.11.0-12-generic i386 3.11.0-12.19 [33.5 MB]
Get:5 http://us.archive.ubuntu.com/ubuntu/ saucy/main indicator-sound i386 12.10.2+13.10.20131011-0ubuntu1 [55.7 kB]
Fetched 43.9 MB in 10min 23s (70.4 kB/s)                                                           
(Reading database ... 174913 files and directories currently installed.)
Preparing to replace bash-completion 1:2.0-1ubuntu3 (using .../bash-completion_1%3a2.0-1ubuntu3_all.deb) ...
Unpacking replacement bash-completion ...
Preparing to replace cheese-common 3.8.3-0ubuntu1 (using .../cheese-common_3.8.3-0ubuntu1_all.deb) ...
Unpacking replacement cheese-common ...
Preparing to replace gnumeric-doc 1.12.6-1 (using .../gnumeric-doc_1.12.6-1_all.deb) ...
Unpacking replacement gnumeric-doc ...
Preparing to replace linux-image-extra-3.11.0-12-generic 3.11.0-12.19 (using .../linux-image-extra-3.11.0-12-generic_3.11.0-12.19_i386.deb) ...
Unpacking replacement linux-image-extra-3.11.0-12-generic ...
Examining /etc/kernel/postrm.d .
run-parts: executing /etc/kernel/postrm.d/initramfs-tools 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
run-parts: executing /etc/kernel/postrm.d/zz-update-grub 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
Preparing to replace indicator-sound 12.10.2+13.10.20131011-0ubuntu1 (using .../indicator-sound_12.10.2+13.10.20131011-0ubuntu1_i386.deb) ...
Unpacking replacement indicator-sound ...
Processing triggers for man-db ...
Processing triggers for libglib2.0-0:i386 ...
No such key 'auto-launch' in schema 'com.ubuntu.update-notifier' as specified in override file '/usr/share/glib-2.0/schemas/20_xubuntu-default-settings.gschema.override'; ignoring override for this key.
Processing triggers for hicolor-icon-theme ...
Setting up bash-completion (1:2.0-1ubuntu3) ...
Setting up cheese-common (3.8.3-0ubuntu1) ...
Setting up gnumeric-doc (1.12.6-1) ...
Setting up linux-image-extra-3.11.0-12-generic (3.11.0-12.19) ...
Running depmod.
update-initramfs: deferring update (hook will be called later)
Not updating initrd symbolic links since we are being updated/reinstalled 
(3.11.0-12.19 was configured last, according to dpkg)
Not updating image symbolic links since we are being updated/reinstalled 
(3.11.0-12.19 was configured last, according to dpkg)
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
run-parts: executing /etc/kernel/postinst.d/dkms 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
update-initramfs: Generating /boot/initrd.img-3.11.0-12-generic
run-parts: executing /etc/kernel/postinst.d/pm-utils 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
run-parts: executing /etc/kernel/postinst.d/update-notifier 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.11.0-12-generic /boot/vmlinuz-3.11.0-12-generic
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.11.0-14-generic
Found initrd image: /boot/initrd.img-3.11.0-14-generic
Found linux image: /boot/vmlinuz-3.11.0-12-generic
Found initrd image: /boot/initrd.img-3.11.0-12-generic
Found memtest86+ image: /boot/memtest86+.bin
Found Windows 7 (loader) on /dev/sda1
done
Setting up indicator-sound (12.10.2+13.10.20131011-0ubuntu1) ...

Наконец, я проверил, чтобы убедиться, что поврежденных файлов не осталось:

$ sudo debsums -c

Вывода из этой команды не было, что означает, что ошибки не найдено. :-)

Одна заключительная заметка: вы также должны проверить конфигурационные файлы ваших пакетов, чтобы убедиться, что они в порядке. Это может быть сложнее, так как конфигурационные файлы часто меняются, и изменения являются законными, поэтому вам нужно вручную проверить каждый изменённый конфигурационный файл, чтобы определить, не повреждён ли он на самом деле. Вот как можно получить список изменённых конфигурационных файлов:

$ sudo debsums -as
debsums: changed file /etc/gnome/defaults.list (from desktop-file-utils package)
debsums: changed file /etc/default/rcS (from initscripts package)
debsums: changed file /etc/subuid (from login package)
debsums: changed file /etc/subgid (from login package)
debsums: changed file /etc/sudoers (from sudo package)
55
ответ дан 23 November 2019 в 00:25

Скрипт, предоставленный PeniWize, отлично работает с поврежденными файлами, но не заботится о пакетах с отсутствующими файлами, так как debsums сообщает об этом в stderr. Чтобы переустановить пакеты с отсутствующими файлами, это сработало со мной:

xargs -rd '\n' -a <(sudo debsums -c 2>&1 | cut -d " " -f 4 | sort -u | xargs -rd '\n' -- dpkg -S | cut -d : -f 1 | sort -u) -- sudo apt-get install -f --reinstall --
13
ответ дан 23 November 2019 в 00:25

Я создал следующий сценарий для восстановления отсутствующие файлы с помощью различных уловок.

Сохраните его в файл dpkg-fix.sh , сделайте его chmod a + x dpkg-fix.sh и запустите sudo ./ dpkg-fix.sh -x .

Заявление об ограничении ответственности / Обратите внимание, что опция -x восстанавливает файлы конфигурации (в / etc), которые не восстанавливаются по умолчанию. Он может промыть вашу систему. Очень сложно создать какой-либо автоматизированный инструмент для правильного восстановления, поскольку файлы конфигурации часто настраиваются. Вы должны сделать резервные копии и после восстановления сравнить различия с вашей последней резервной копией и сделать некоторые выводы. Даже после этого разработайте план, как тестировать каждое изменение, поскольку есть возможность серьезно нарушить работу, не имея средств для восстановления.

#! /bin/bash

## (c) 2020 IVA2K

# Must be root
if [ $(id -u) -ne 0 ]; then
  printf "Must be root. Did you use 'sudo'?\n"
  exit 1
fi

do_install () {
  echo "Installing debsums:"
  apt-get install debsums

  echo "Initializing debsums (might take a while)..."
  debsums_init

  echo "Done Installing & Initializing debsums."
  exit 0
}

# Based on ideas from https://askubuntu.com/a/392326
# $1=debsums arg $2=0(no err) 1(catch debsums stderr) $3=fix|no_fix
do_debsums_parse () {
  echo "Scanning for changed or missing files (debsums ${1} errs=${2} > debsums${1}${2}.log)..."
  if [ "${2}" -ne "0" ]; then
    IFS=$'\n' readarray -t badfiles <<< "$(debsums "${1}" 2>&1)"
  else
    IFS=$'\n' readarray -t badfiles <<< "$(debsums "${1}" 2>/dev/null)"
  fi

  IFS=$'\n' printf '%s\n' "${badfiles[@]}" >debsums${1}${2}.log

  unset files
  unset packages

  # set IFS to  allow "for" in array with elements containing spaces. Ugly bash!
  local IFS=$'\n'
  for line in "${badfiles[@]}" ; do
    IFS=' ' read -a fields <<< "${line}"
    #echo "DEBUG: line=$line fields=${fields[@]}"

    # set IFS to allow "if" of arrays to compare to strings. Ugly bash!
    local IFS=$' '
    if [ "${#line}" -eq "0" ] ; then
      echo -e ;# skip empty lines
    elif [ "${fields[*]:0:4}" = "debsums: no md5sums for" ] ; then
      local IFS=$'\n'
      package="${fields[@]:4:1}"
      echo "DEBUG: no md5sums package=$package"
      packages=(${packages[@]} "$package")
    elif [ "${fields[*]:0:3}" = "debsums: changed file" ] ; then
      local IFS=$'\n'
      file="${fields[@]:3:1}"
      package=$( dpkg -S ${file} | cut -d : -f 1)
      echo "DEBUG: changed file=$file package=$package"
      files=(${files[@]} "$file")
      packages=(${packages[@]} "$package")
    elif [ "${fields[*]:0:3}" = "debsums: missing file" ] ; then
      local IFS=$'\n'
      file="${fields[@]:3:1}"
      package=$( dpkg -S ${file} | cut -d : -f 1)
      echo "DEBUG: missing file=$file package=$package"
      files=(${files[@]} "$file")
      packages=(${packages[@]} "$package")
    elif [ "${#fields[@]}" -eq "1" ] ; then
      local IFS=$'\n'
      file="${fields[@]:0:1}"
      package=$( dpkg -S ${file} | cut -d : -f 1)
      echo "DEBUG: changed file=$file package=$package"
      files=(${files[@]} "$file")
      packages=(${packages[@]} "$package")
    elif [ "${fields[*]:0:3}" = "debsums: symlink loop" ] ; then
      local IFS=$'\n'
      file="${fields[@]:8:1}"
      package=$( dpkg -S ${file} | cut -d : -f 1)
      echo "DEBUG: symlink loop file=$file package=$package"
      files=(${files[@]} "$file")
      packages=(${packages[@]} "$package")
    else
      local IFS=$' '
      echo "WARNING: unrecognized line='$(declare -p line)' fields='$(declare -p fields)' test1:'${fields[*]:0:4}' test2:'${fields[*]:0:3}'"
    fi

  done

  local IFS=$' '
  if [ "${#files[@]}" -gt "0" ] ; then
    local IFS=$'\n'
    readarray -t files <<< "$(printf '%s\n' "${files[@]}" | sort -u)"
  fi
  local IFS=$' '
  if [ "${#packages[@]}" -gt "0" ] ; then
    local IFS=$'\n'
    readarray -t packages <<< "$(printf '%s\n' "${packages[@]}" | sort -u)"
  fi

  echo "Changed or missing ${#files[@]} files (files${1}${2}.log):"
  echo ${files[*]}
  echo
  IFS=$'\n' printf '%s\n' "${files[@]}" >files${1}${2}.log

  echo "${#packages[@]} packages with changed or missing files (packages${1}${2}.log):"
  echo ${packages[*]}
  echo
  IFS=$'\n' printf '%s\n' "${packages[@]}" >packages${1}${2}.log

  if [ "${3}" = "fix" ]; then
    local IFS=$' '
    if [ "${#packages[@]}" -gt "0" ] ; then
      echo "Reinstalling ${#packages[@]} packages:"
      apt-get install -f --reinstall -o Dpkg::Options::=--force-confmiss ${packages[@]}
      echo
    fi
    
    #local IFS=$'\n'
    #for package in "${packages[@]}" ; do
    #  # special effort to restore missing configuration files from the package
    #  # (it includes scripts in /etc/*, which apt/dpkg will not reinstall by default)
    #  dpkg -i --force-confmiss /var/cache/apt/archives/${package}*.deb
    #done
    
    if [ -f "$(which debsums).patched" ]; then
      echo "Reapplying debsums patch:"
      cp -vf "$(which debsums)" "$(which debsums).orig"
      cp -v  "$(which debsums).patched" "$(which debsums)"
      echo
    fi
    
    echo "Done fixing ${#files[@]} changed or missing files, ${#packages[@]} packages."
  else
    echo "Done scanning: ${#files[@]} changed or missing files, ${#packages[@]} packages."
  fi
  echo

  exit 0
}

case "$1" in
  -i|install)
    do_install
    ;;
  -s|check_sums|"")
    do_debsums_parse "-cs" 0 no_fix
    ;;
  -c|check_changed)
    do_debsums_parse "-as" 1 no_fix
    ;;
  -f|fix_corrupt)
    do_debsums_parse "-c" 0 fix
    ;;
  -m|fix_missing)
    do_debsums_parse "-c" 1 fix
    ;;
  -x|fix_missing_config)
    do_debsums_parse "-as" 1 fix
    ;;
  *)
    echo "Usage: $0 [ -i|install | -s|check_sums | -c|check_changed | -f|fix_corrupt | -m|fix_missing | -x|fix_missing_config ]" >&2
    exit 3
    ;;
esac



1
ответ дан 5 January 2021 в 23:51

Другие вопросы по тегам:

Похожие вопросы: