Обнаружение и удаление поврежденных файлов с нулевым заполнением эффективно и надежно

Обнаружение и удаление поврежденных файлов с нулевым заполнением эффективно и надежно

28.01.2020 11:31:15 Просмотров 19 Источник

Переносимая функция оболочки / скрипт для проверки файлов, заполненных нулевыми байтами

Я думал о том, чтобы посмотреть на сигнатуры файлов, магические байты и т. д., Но я не хочу использовать какие-либо косвенные предположения (кроме, скажем, известного механизма, такого как вывод hexdump ниже)

Это то, что я использую сейчас:

#!/bin/bash 

file="$1" 
bail () { 
    >&2 echo "$file doesn't exist" 
    exit 1 
} 

[ -f "$1" ] ; [[ "$?" != 0 ]] && bail                     # Check valid filename
result="$(head -c4 "$file" | hexdump -ve '1/1 "%.2X"')"   
if [ "$result" == "0000" ] || [ "$result" == "00000000" ] # Get first 4 bytes as pre-condition
    then                                                                                                    # Check for large contiguous blocks of null 
        head -c10000 "$file" | hexdump | \
        if [[ "$(wc -l <<<"$(cat -)")" -le 4 ]]           # By virtue of pre-condition, all output must be null
        then 
            exit 2                                        # Exit Codes
         else 
            exit 0                                         # 0: File is good
        fi                                                 # 1: Validation error
    else                                                   # 2: File is cactus
        exit 0
fi                            

Идея в том, что:

  • Проверьте первые 4 байта как предварительное условие
  • Использование hexdump без -v группе несколько наборов предпосылки (нулевые байты)
  • Использовать head -c1K для ограничения чрезмерного производства внутренне
  • Используйте wc -lпроверить для Любое другое означало бы изменение от нуля.

И причина некоторого дурацкого и косвенного синтаксиса заключается в том, что bashна некоторых машинах дает мне этот bash: warning: command substitution: ignored null byte in input,и я нашел это, чтобы обойти его.

Повторение файла через вышеизложенное кажется медленным, но в настоящее время можно использовать:

real    0m0.026s
user    0m0.009s
sys     0m0.021s


Есть ли лучший и более эффективный способ сделать это ?

У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106009878_59944751
Хорошо объяснено в этом перекрестном сайте dupe, как найти файлы со 100% нулевыми символами в их содержании?
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106009886_59944751
@MarkSetchell но файлы могут иметь законные нулевые байты в них.
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106009961_59944751
Спасибо @Inian-но некоторые из этих типов решений я уже пробовал. Ключ-это переносимость, а grep с регулярным выражением perl-нет. Я знаю, пока у меня есть некоторый синтаксис bash 4+ здесь, но это работа в процессе
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106010008_59944751
@Inian Действительно. Позвольте мне сделать несколько тестов
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106010080_59944751
1,5 миллиона файлов позже
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106010309_59944751
Я предлагаю вам искать первый ненулевой байт, который будет означать, что файл не полностью состоит из нулевых байтов. Затем остановитесь на первом матче, чтобы избежать чтения остальной части файла.
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106014127_59944751
@hmedia1 вы должны добавить все разъяснения или справочную информацию к вопросу вместо написания комментариев.
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably#comment106014791_59944751
@ Bodo, нет, лучше я буду придерживаться того, что мне нужно, а не раздувать вопрос бесконечно.

Ответы - Обнаружение и удаление поврежденных файлов с нулевым заполнением эффективно и надежно / Detecting and removing corrupt null-filled files efficiently and reliably

Является ответом!
pjh

28.01.2020 10:07:30

Если все системы, в которых вам нужно выполнить проверку, поддерживают /dev / zero, то вы можете проверить, содержит ли файл только нулевые байты с:

[[ $(LC_ALL=C cmp -- "$file" /dev/zero 2>&1) == 'cmp: EOF on '* ]]
  • Страница руководства POSIX для cmp(cmp (The Open Group Base Specifications Issue 7) ) дает точную спецификацию для вывода STDERR в языковом стандарте POSIX. LC_ALL=Cзаставляет cmpиспользовать Локаль POSIX, поэтому сравнение с 'cmp: EOF on '*будет работать правильно.
  • Тест верен для пустых файлов. Если вы этого не хотите, вы можете добавить в тест чек на непустой: [[ -s $file && ... ]].
  • --in the cmpзащищают файлы с именами, начинающимися с -, которые рассматриваются как параметры cmp.
  • Остерегайтесь очень больших файлов или файлов, которые кажутся очень большими ( разреженные файлы ). cmpможет занять очень много времени для работы с такими файлами. Возможно, вы захотите пропустить файлы, размер которых превышает пороговое значение.
https://stackoverflow.com/questions/59944751/detecting-and-removing-corrupt-null-filled-files-efficiently-and-reliably/59955469#comment106031373_59955469
Нереальный. Какое прекрасное решение. Спасибо
Закрыть X