Знайдіть файл, коли знаєте його контрольну суму?


30

У мене є md5sumфайл, і я не знаю, де він знаходиться в моїй системі. Чи є якийсь простий варіант findвизначити файл на основі його md5? Або мені потрібно розробити невеликий сценарій?

Я працюю над AIX 6 без інструментів GNU.


4
Чи не звузить пошук розмір файлів однакового розміру, а потім обчислити md5 буде швидше?
RJ-

@ RJ - так, можливо, але в цьому випадку це також дозволяє мені перевірити, чи файл правильний і чи передано правильно.
Ківі

Відповіді:


34

Використання find:

find /tmp/ -type f -exec md5sum {} + | grep '^file_md5sum_to_match'

Якщо ви здійснюєте пошук, /ви можете виключити /procта /sysпереглянути наступний findприклад команди:

Крім того, я провів тестування, findзабирайте більше часу і менше процесора та оперативної пам’яті, де сценарій рубіну займає менше часу, але більше процесора та оперативної пам’яті

Результати тесту

Знайдіть

[root@dc1 ~]# time find / -type f -not -path "/proc/*" -not -path "/sys/*" -exec md5sum {} + | grep '^304a5fa2727ff9e6e101696a16cb0fc5'
304a5fa2727ff9e6e101696a16cb0fc5  /tmp/file1


real    6m20.113s
user    0m5.469s
sys     0m24.964s

Знайдіть с -prune

[root@dc1 ~]# time find / \( -path /proc -o -path /sys \) -prune -o -type f -exec md5sum {} + | grep '^304a5fa2727ff9e6e101696a16cb0fc5'
304a5fa2727ff9e6e101696a16cb0fc5  /tmp/file1

real    6m45.539s
user    0m5.758s
sys     0m25.107s

Рубін Сценарій

[root@dc1 ~]# time ruby findm.rb
File Found at: /tmp/file1

real    1m3.065s
user    0m2.231s
sys     0m20.706s

Ви хочете зателефонувати -pruneв /sys/ /procзамість того , щоб спуститися в них і виключити файли з -path. Вам слід віддати перевагу !над -notпортативністю.
Стефан Шазелас

Сер, я оновив -prune, раз перевірте, чи це нормально.
Рахул Патіль

Ви також бажаєте виключити /dev.
Саймон Ріхтер

12

Рішення сценарію

#!/usr/bin/ruby -w

require 'find'
require 'digest/md5'

file_md5sum_to_match = [ '304a5fa2727ff9e6e101696a16cb0fc5',
                         '0ce6742445e7f4eae3d32b35159af982' ]

Find.find('/') do |f|
  next if /(^\.|^\/proc|^\/sys)/.match(f) # skip
  next unless File.file?(f)
  begin
        md5sum = Digest::MD5.hexdigest(File.read(f))
  rescue
        puts "Error reading #{f} --- MD5 hash not computed."
  end
  if file_md5sum_to_match.include?(md5sum)
       puts "File Found at: #{f}"
       file_md5sum_to_match.delete(md5sum)
  end
  file_md5sum_to_match.empty? && exit # if array empty then exit

end

Рішення Bash Script на основі ймовірності, яка працює швидше

#!/bin/bash
[[ -z $1 ]] && read -p "Enter MD5SUM to search file: " md5 || md5=$1

check_in=( '/home' '/opt' '/tmp' '/etc' '/var' '/usr'  )
last_find_cmd="find / \\( -path /proc -o -path /sys ${check_in[@]/\//-o -path /} \\) -prune -o -type f -exec md5sum {} +"
last_element=${#check_in}
echo "Please wait... searching for file"
for d in ${!check_in[@]}
do

        [[ $d == $last_element ]] && eval $last_find_cmd | grep "^${md5}" && exit

        find ${check_in[$d]} -type f -exec md5sum {} + | grep "^${md5}" && exit


done

Результати тесту

[root@dc1 /]# time bash find.sh 304a5fa2727ff9e6e101696a16cb0fc5
Please wait... searching for file
304a5fa2727ff9e6e101696a16cb0fc5  /var/log/file1

real    0m21.067s
user    0m1.947s
sys     0m2.594s

що б ти порадив?
Ківі

@Kiwy Мені не рекомендується, Просто на практиці
Рахул Патіль

@Kiwy раз подивіться на результат тестування і дайте мені знати, а також зробіть кілька тестувань з вашого боку та покажіть нам результат, було б чудово побачити результат на AIX. : D
Рахул Патіль

Моя головна проблема вашого сценарію полягає в тому, що він потребує рубіну, і він не встановлюється в моїй системі, і я не адміністратор. але я пройду тест сьогодні ввечері, якщо знайду якийсь час
Ківі

Здається, швидше, ніж знайти в підсумку ^^. можливо, ви могли б покласти md5sum у нитку, щоб ви могли обчислити 5 md5sum одночасно, це могло б також заощадити трохи часу
Kiwy

7

Якщо ви все-таки вирішите встановити gnu find (а оскільки ви виявили зацікавленість в одному зі своїх коментарів), ви можете спробувати щось на кшталт:

find / -type f \( -exec checkmd5 {} YOURMD5SUM \; -o -quit \) 

і checkmd5порівняйте md5sum файла, який він отримує як аргумент, порівняйте з другим аргументом і надрукуйте ім'я, якщо воно збігається, і вийдіть з 1 (замість 0 в іншому випадку). Після того, як вона буде знайдена, зупинка -quitбуде findзупинена.

checkmd5 (не перевірено):

#!/bin/bash

md=$(md5sum $1 |  cut -d' ' -f1)

if [ $md == $2 ] ; then
  echo $1
  exit 1
fi
exit 0

Так No package checkmd5 available, будь ласка, включіть, для якого пакета потрібно встановитиcheckmd5
Rahul Patil

Мені подобається це рішення занадто погане, я не розумію, checkmd5але мені подобається те, як ви це робите
Ківі

Додано сценарій @kiwy.
Антон

@RahulPatil він у розпорядженні DIY ;-)
Anthon

@kiwy Вибачте, я міг прийняти вашу редакцію -type f, але це змінило мою, яку echo $1я вже помістив
Антон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.