sha1sum สำหรับไดเรกทอรีของไดเรกทอรี


33
sha1sum ./path/to/directory/* | sha1sum 

ข้างต้นถูกโพสต์เป็นวิธีการคำนวณ sha1sum ของไดเรกทอรีที่มีไฟล์ คำสั่งนี้ล้มเหลวหากไดเรกทอรีมีไดเรกทอรีเพิ่มเติม มีวิธีในการคำนวณ sha1sum ของไดเรกทอรีของไดเรกทอรีซ้ำ ๆ (โดยไม่ต้องปรับแต่งอัลกอริทึมให้เหมาะสมกับไดเรกทอรีที่ต้องการ) หรือไม่?

คำตอบ:


14

ขอบคุณโพสต์นี้ -

find . -type f \( -exec sha1sum "$PWD"/{} \; \) | sha1sum

คำเตือน: รหัสนี้ยังไม่ได้ทดสอบ ! แก้ไขคำถามนี้ถ้ามันผิดและคุณสามารถแก้ไขได้ ฉันจะอนุมัติการแก้ไขของคุณ


ขออภัย; ฉันไม่สามารถต้านทาน! ;-) การค้นหาซ้ำเป็นเรื่องสนุก แน่นอนว่ามันมีวิธี ฉันจะเขียนคำตอบที่เหมาะสมตอนนี้
allquixotic

3
สิ่งนี้จะไม่สร้างแฮชเดียวกันสำหรับโฟลเดอร์เดียวกันที่แน่นอนในเครื่องที่แตกต่างกันเนื่องจากเอาต์พุตยังมี <hash> และ <file path> ซึ่งพา ธ ของไฟล์ที่แตกต่างกันในเครื่องที่แตกต่างกันและทำให้แฮชต่างกันในเครื่องที่แตกต่างกัน บรรทัดที่ถูกต้องควรเป็นfind . -type f \( -exec sha1sum "$PWD"/{} \; \) | awk '{print $1}' | sort | sha1sum@allquixotic
alper

1
นอกจากนี้ควรมีการเรียงลำดับของแฮชของไฟล์ซึ่งจะทำให้แฮชแตกต่างกันหากลำดับการเรียงนั้นแตกต่างกันในเครื่องที่แตกต่างกัน
Alper

40

ฉันมักชอบรูปแบบ "find | xargs" เช่น:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

คุณต้องใช้ "-print0" และ "-0" ในกรณีที่มีช่องว่างในชื่อไฟล์

อย่างไรก็ตามนี่คล้ายกับรูปแบบ "find -exec cmd {}"

ดูการสนทนาเปรียบเทียบสองรูปแบบได้ที่นี่: https://stackoverflow.com/questions/896808/find-exec-cmd-vs-xargs


คำตอบของคุณจะส่งคืนไฟล์แฮชเท่านั้น find . -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sumกัญชาของโฟลเดอร์ที่ควรจะได้ใช้
alper

5

UPDATE:ไม่กี่ปีที่ผ่านมาตั้งแต่ฉันโพสต์คำตอบนี้และในขณะเดียวกันฉันได้เขียนใหม่และปรับปรุงสคริปต์ที่ฉันนำเสนอที่นี่หลายครั้ง ฉันตัดสินใจที่จะโพสต์สคริปต์ใหม่เป็นคำตอบใหม่ ฉันอยากจะแนะนำที่นี่มากกว่านี้

บทนำ

ฉันสังเกตว่าลำดับที่คำสั่ง find ส่งออกองค์ประกอบที่พบภายในไดเรกทอรีนั้นจะแตกต่างกันไปในแต่ละไดเรกทอรีในพาร์ติชันที่ต่างกัน หากคุณกำลังเปรียบเทียบแฮชของไดเรกทอรีเดียวกันคุณไม่ต้องกังวลเกี่ยวกับสิ่งนั้น แต่ถ้าคุณได้รับแฮชเพื่อให้แน่ใจว่าไม่มีไฟล์ใดที่พลาดหรือเสียหายระหว่างการคัดลอกคุณจะต้องรวมบรรทัดเพิ่มเติมสำหรับ การเรียงลำดับเนื้อหาของไดเรกทอรีและองค์ประกอบ ตัวอย่างเช่นคำตอบของ Matthew Bohnsack นั้นค่อนข้างงดงาม:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

แต่ถ้าคุณใช้มันเพื่อเปรียบเทียบไดเรกทอรีที่คัดลอกไปเป็นของจริงคุณจะส่งผลลัพธ์ไปยังไฟล์ txt ซึ่งคุณจะเปรียบเทียบกับรายการเอาท์พุทจากไดเรกทอรีอื่นโดยใช้ Kompare หรือ WinMerge หรือเพียงแค่รับ hash ของแต่ละ lis . สิ่งที่ตามมาคือลำดับที่เครื่องมือค้นหาจะส่งออกเนื้อหาอาจแตกต่างจากไดเรกทอรีหนึ่งไปอีกไดเรกทอรีหนึ่ง Kompare จะส่งสัญญาณความแตกต่างมากมายเนื่องจากแฮชไม่ได้มีการคำนวณในลำดับเดียวกัน ไม่ใช่เรื่องใหญ่สำหรับไดเรกทอรีขนาดเล็ก แต่ค่อนข้างน่ารำคาญถ้าคุณจัดการกับไฟล์ 30000 ดังนั้นคุณได้ทำขั้นตอนพิเศษในการเรียงลำดับผลลัพธ์เพื่อให้ง่ายต่อการเปรียบเทียบรายการแฮชระหว่างสองไดเรกทอรี

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum > sha1sum_list_unsorted.txt
sort sha1sum_list_unsorted.txt > sha1sum_list_sorted.txt

สิ่งนี้จะเรียงลำดับผลลัพธ์เพื่อให้ไฟล์ที่มีแฮชเดียวกันกำลังจะอยู่ในบรรทัดเดียวกันเมื่อรันโปรแกรม differencing (โดยที่ไฟล์นั้นไม่มีไฟล์ใดขาดไดเรกทอรีใหม่)

และบนสคริปต์ ...

นี่คือสคริปต์ที่ฉันเขียน มันทำในสิ่งเดียวกันกับที่คำตอบ find / xarg ทำ แต่จะเรียงลำดับไฟล์ก่อนรับ sha1sum (เก็บไว้ในไดเรกทอรีเดียวกัน) บรรทัดแรกของสคริปต์จะค้นหาไฟล์ทั้งหมดในไดเรกทอรีซ้ำ รายการถัดไปเรียงลำดับตามตัวอักษร สองรายการต่อไปนี้นำเนื้อหาที่เรียงลำดับแล้วผนวก sha1sum และเครื่องหมายคำพูดไปยังไฟล์ในรายการที่เรียงลำดับสร้างเชลล์สคริปต์ขนาดใหญ่ที่คำนวณแต่ละไฟล์แฮชทีละไฟล์และส่งไปที่ content_sha1sum.txt

#!/bin/bash
find . -type f > content.txt
sort content.txt > content_sorted.txt
awk '{print "sha1sum \""$0}' content_sorted.txt > temp.txt
awk '{print $0"\""}' temp.txt > get_sha1.sh
chmod +x get_sha1.sh
./get_sha1.sh > content_sha1sum.txt
rm content.txt
rm content_sorted.txt
rm temp.txt
rm get_sha1.sh
xdg-open content_sha1sum.txt

หวังว่านี่จะช่วยได้


เมื่อความยาวทั้งหมดของชื่อไฟล์ทั้งหมดพอดีภายในบรรทัดคำสั่งการไพพ์ผ่านsort -z( --zero-terminated) จะง่ายกว่าการยุ่งกับไฟล์จำนวนมาก
Anton Samsonov

@AntonSamsonov นี่เป็นสคริปต์ที่เก่าแก่มากฉันเพิ่งเรียนรู้การเขียนสคริปต์ในเวลานั้น ฉันได้เขียนมันใหม่มาหลายครั้งแล้ว ในเรื่องที่เกี่ยวกับความคิดเห็นของคุณสิ่งที่เป็นศูนย์การยกเลิกจะทำอย่างไรในการเรียงลำดับ: ฉันอ่าน man page ของ sort พวกเขาบอกว่าศูนย์ยุติติดศูนย์ไบต์ที่ท้ายบรรทัดแทนที่จะขึ้นบรรทัดใหม่ อะไรที่ทำให้สำเร็จ
thebunnyrules

ฉันโพสต์การอัปเดตของสคริปต์นี้เป็นคำตอบที่แยกต่างหากที่นี่: superuser.com/questions/458326//
thebunnyrules

4

บทนำ

ไม่กี่ปีที่ผ่านมาฉันเขียนและนำเสนอ (ในชุดข้อความนี้มาก) สคริปต์ที่สามารถตรวจสอบลายเซ็นแฮชของไฟล์แต่ละไฟล์ทั้งหมดในโครงสร้างไดเรกทอรีปัจจุบันและส่งออกเป็นรายการในไฟล์ข้อความ

ตั้งแต่นั้นมาฉันได้ปรับปรุงสูตรนี้หลายครั้ง ฉันตัดสินใจที่จะโพสต์สคริปต์ใหม่และปรับปรุงของฉันที่นี่เป็นคำตอบที่แยกต่างหาก มันเขียนขึ้นสำหรับ sha256 แต่ทุกคนที่ยังต้องการใช้ sha1 สามารถทำการค้นหาง่าย ๆ และแทนที่ด้วย gedit เพื่อแลกเปลี่ยน sha256 ด้วย sha1 โดยส่วนตัวแล้วฉันไม่ได้ใช้ sha1 มาสองปีแล้วและฉันจะไม่แนะนำให้ใช้เพราะมันเป็นของเก่าและgoogle ได้แสดงให้เห็นว่ามันจะถูกบุกรุกได้อย่างไร

นี่คือสิ่งที่สคริปต์ใหม่ของฉันทำ:

  1. คุณสามารถใช้สคริปต์โดยไปที่ไดเรกทอรีที่คุณต้องการแฮชและการป้อน:

    sha256rec

    หรือคุณสามารถเรียกสคริปต์นี้จากไดเรกทอรีอื่นโดยทำดังนี้

    sha256rec "/path/to/target/directory/you/want/hash"
  2. สคริปต์จะตรวจพบว่าคุณมีสิทธิ์เขียนใน dir ปัจจุบัน หากคุณทำเช่นนั้นผลลัพธ์จะถูกบันทึกไว้ในไดเรกทอรีปัจจุบัน หากคุณไม่มีสิทธิ์ในการเขียนหรือหากไดเรกทอรีปัจจุบันของคุณอยู่ในระบบแบบอ่านอย่างเดียว (เช่น cdrom) ผลลัพธ์จะถูกบันทึกลงในโฮมไดเรกทอรีของผู้ใช้ปัจจุบัน

  3. สคริปต์จะตรวจสอบว่าบางส่วนของไดเรกทอรีย่อยไม่สามารถเข้าถึงได้ที่สิทธิ์ผู้ใช้ปัจจุบัน หากทุกคนสามารถอ่านได้จะไม่มีการยกระดับสิทธิ์หากไม่เป็นเช่นนั้นสิทธิ์ของผู้ใช้จะถูกยกระดับเป็นรูท

  4. Find ใช้เพื่อค้นหาไฟล์ทั้งหมดในโครงสร้าง dir ปัจจุบัน (รวมถึงไดเรกทอรีย่อยทั้งหมด) จัดเรียงจะใช้เพื่อให้แน่ใจว่าผลลัพธ์จะถูกส่งออกตามตัวอักษร รายการผลลัพธ์จะผ่าน sha256sum และถูกส่งออกไปยังไฟล์ข้อความ

  5. ตั้งแต่การเขียนสคริปต์เก่าฉันได้นำปรัชญาการออกแบบมาใช้ว่าไฟล์ temp นั้นชั่วร้ายและควรหลีกเลี่ยงเมื่อเป็นไปได้เนื่องจากพวกเขาเปิดให้ผู้ใช้เปิดการสอดแนมและแก้ไขโดยบุคคลที่สามที่เป็นอันตราย ดังนั้นข้อมูลทั้งหมดในสคริปต์ใหม่นี้จะถูกจัดการเป็นตัวแปรจนกระทั่งนาทีสุดท้ายที่ผลลัพธ์จะถูกส่งออกเป็นไฟล์ข้อความ

  6. ไฟล์ผลลัพธ์เองถูกแฮชและพา ธ / แฮชจะถูกส่งออกในเทอร์มินัล ฉันชอบถ่ายรูปแฮชเหล่านี้ด้วยกล้องออฟไลน์ของโรงเรียนเก่าเพื่อให้แน่ใจว่าไฟล์ผลลัพธ์จะไม่ถูกแก้ไขเมื่อฉันอ้างถึงในภายหลัง

  7. ไฟล์ผลลัพธ์เก่าจะถูกละเว้นในการนับ มันทำให้การเปรียบเทียบผลลัพธ์ง่ายขึ้น

นี่คือตัวอย่างของเอาต์พุตเทอร์มินัลเมื่อรันสคริปต์ของฉัน:

kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ sha256rec
======================================================================= 
sha256rec:         
=======================================================================        
Current Folder : /usr/src/linux-headers-4.13.0-16-generic   
Target Folder  : /usr/src/linux-headers-4.13.0-16-generic
Output File    : /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt


Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder.
f3ddb06212622c375c6bcc11bd629ce38f6c48b7474054ca6f569ded4b4af9d8  /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt
Operation Length: 10 Seconds.
=======================================================================
kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ 

นี่คือตัวอย่างของผลลัพธ์ที่สามารถพบได้ใน 000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt:

79c3f378a42bd225642220cc1e4801deb35c046475bb069a96870ad773082805  ./.9491.d
2e336c69cde866c6f01a3495048d0ebc2871dd9c4cb5d647be029e0205d15ce6  ./.config
174f23ff7a7fba897bfb7cf17e9a501bcecacf7ef0c0d5cf030414c1e257d4e3  ./.config.old
389d83f546b250304a9a01bb3072ff79f9d9e380c8a2106cadbf714a872afe33  ./.missing-syscalls.d
035dc77da819101cb9889b4e515023dddd2c953f00d2653b87c6196a6560903e  ./Module.symvers
b28054d7995233e6d003ceb9ed119a0b3354f5ccf77b8d687fc0353ae3c5bfb8  ./arch/x86/include/generated/asm/.syscalls_32.h.cmd
01cf821170e3e6e592e36a96e8628377151c762ac2ee3210c96004bfaef22f5f  ./arch/x86/include/generated/asm/.syscalls_64.h.cmd
111efa83187c58a74a9b0170fd496b497b0682d109a7c240c17e2ffcc734f4f4  ./arch/x86/include/generated/asm/.unistd_32_ia32.h.cmd
fcba4e8abf9e95472c31708555db844ac43c87260fb0ba706b6f519404bf9aba  ./arch/x86/include/generated/asm/.unistd_64_x32.h.cmd
3264438a54cbf7e62b05d38a93c5df8fe4202ac782a5d83ed202cba9eee71139  ./arch/x86/include/generated/asm/.xen-hypercalls.h.cmd
4bd7a45837da7de379b87242efe562ce06bf9d8ab8f636c205bb5ef384c8f759  ./arch/x86/include/generated/asm/clkdev.h
0d96461abd23bbf2da522822948455413a345f9ef8ac7a7f81c6126584b3c964  ./arch/x86/include/generated/asm/dma-contiguous.h
b1a54c24a12ce2c0f283661121974436cdb09ae91822497458072f5f97447c5d  ./arch/x86/include/generated/asm/early_ioremap.h
dd864107295503e102ea339e0fd4496204c697bdd5c1b1a35864dfefe504a990  ./arch/x86/include/generated/asm/mcs_spinlock.h
782ce66804d000472b3c601978fa9bd98dcf3b2750d608c684dc52dd1aa0eb7e  ./arch/x86/include/generated/asm/mm-arch-hooks.h
cd9913197f90cd06e55b19be1e02746655b5e52e388f13ec29032294c2f75897  ./arch/x86/include/generated/asm/syscalls_32.h
758ce35908e8cfeec956f57a206d8064a83a49298e47d47b7e9a7d37b5d96d59  ./arch/x86/include/generated/asm/syscalls_64.h
1147ca3a8443d9ccbdf9cd1f4b9b633f0b77f0559b83ec5e4fa594eadb2548be  ./arch/x86/include/generated/asm/unistd_32_ia32.h
ca5223fbf8f03613a6b000e20eb275d9b8081c8059bc540481a303ce722d42f3  ./arch/x86/include/generated/asm/unistd_64_x32.h
31703052c0d2ab8fe14b4e5dfcc45fcbd5feb5016b0a729b6ba92caa52b069e2  ./arch/x86/include/generated/asm/xen-hypercalls.h
c085ff1b6e9d06faa3fc6a55f69f9065c54098d206827deec7fe0a59d316fc99  ./arch/x86/include/generated/uapi/asm/.unistd_32.h.cmd
7929c16d349845cebb9e303e0ff15f67d924cac42940d0f7271584f1346635fc  ./arch/x86/include/generated/uapi/asm/.unistd_64.h.cmd
9aa492c5a75f5547f8d1dc454bef78189b8f262d1c4b00323a577907f138a63e  ./arch/x86/include/generated/uapi/asm/.unistd_x32.h.cmd
f568e151bbbb5d51fd531604a4a5ca9f17004142cd38ce019f0d5c661d32e36b  ./arch/x86/include/generated/uapi/asm/unistd_32.h
c45cf378498aa06b808bb9ccf5c3c4518e26501667f06c907a385671c60f14ae  ./arch/x86/include/generated/uapi/asm/unistd_64.h
a0088d8d86d7fd96798faa32aa427ed87743d3a0db76605b153d5124845161e2  ./arch/x86/include/generated/uapi/asm/unistd_x32.h
e757eb6420dffa6b24b7aa38ca57e6d6f0bfa7d6f3ea23bbc08789c7e31d15fa  ./arch/x86/kernel/.asm-offsets.s.cmd
f9e703e4f148d370d445c2f8c95f4a1b1ccde28c149cff2db5067c949a63d542  ./arch/x86/kernel/asm-offsets.s
7971fb3e0cc3a3564302b9a3e1ad188d2a00b653189968bbc155d42c70ce6fbf  ./arch/x86/purgatory/.entry64.o.cmd
8352d79fe81d2cf694880f428e283d79fd4b498cea5a425644da25a9641be26b  ./arch/x86/purgatory/.kexec-purgatory.c.cmd
37f3edbee777e955ba3b402098cb6c07500cf9dc7e1d44737f772ac222e6eb3e  ./arch/x86/purgatory/.purgatory.o.cmd
bb8b895cbd2611b69e2f46c2565b4c2e63a85afb56cff946a555f2d277ee99b2  ./arch/x86/purgatory/.purgatory.ro.cmd
bcc2365c9d3d027f1469806eb4f77b0f3ede6eb0855ea0fcd28aa65884046a54  ./arch/x86/purgatory/.setup-x86_64.o.cmd
872229f334fdcc8562e31b9f6581008c1571ac91f12889cd0ff413590585155a  ./arch/x86/purgatory/.sha256.o.cmd
6fb0cbef120aadee282f7bc3b5ea2f912980f16712281f8f7b65901005194422  ./arch/x86/purgatory/.stack.o.cmd
cd1b61063ae3cf45ee0c58b2c55039f3eac5f67a5154726d288b4708c4d43deb  ./arch/x86/purgatory/.string.o.cmd
e5826f0216fd590972bbc8162dd175f87f9f7140c8101505d8ca5849c850ec91  ./arch/x86/purgatory/entry64.o

(มันจะมีต่อไปอีก 7,000 บรรทัดเช่นนี้ แต่คุณจะได้แนวคิด)

การติดตั้ง

  1. เปิดเทอร์มินัลและป้อนคำสั่งต่อไปนี้:

    cd /usr/bin
    sudo su
    echo '#!/bin/bash'> /usr/bin/sha256rec
    chmod +x /usr/bin/sha256rec
    touch /usr/bin/sha256rec
    nano /usr/bin/sha256rec
  2. ใน nano ใช้ Shif + Ctrl + v เพื่อวาง Ctrl-O และ Enter เพื่อบันทึก ออกจาก Ctr-X วางสคริปต์ของฉันไว้ที่นั่น:

(วางหลังจาก #! / bin / bash)

  #FUNCTIONS OR FUNCTYOU?
  function s_readonly { err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; echo $(cat /tmp/$err|grep -i "Read-only file system"|wc -l);shred -n 0 -uz /tmp/$err; }
  function w_denied { echo $(err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function r_denied { echo $(err=$(date +%s%N); cd "$1" >/dev/null 2> /tmp/$err; find . >/dev/null 2>> /tmp/$err; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function rando_name { rando=$(echo $(date +%s%N)|sha256sum|awk '{print $1}'); rando=${rando::$(shuf -i 30-77 -n 1)}; echo $rando;}
  function ms0 { ms0=$(($(date +%s%N)/1000000)); }; function mstot { echo $(($(($(date +%s%N)/1000000))-$ms0));}
  function s0 { s0=$(date +%s); }; function stot { echo $(($(date +%s)-$s0));}
  s0

  #CHECK IF A TARGET DIR WAS SPECIFIED (-t= or --target= switch)
  if [ ! -z "$1" ]; then arg1="$1"; arg1_3=${arg1::3}; arg1_9=${arg1::9};fi
  if [ "$arg1_3" = "-t=" -o "$arg1_9" = "--target=" ]; then 
    switch=$(echo $arg1|awk -F '=' '{print $1}')
    switch_chr=$((${#switch}+1))
    target=${arg1:$switch_chr}
    current=$(pwd)
    cd "$target"
    arg1="" #<- cancels the not path in the find line
  else
    current=$(pwd)
    target=$(pwd) 
  fi

  echo -e  "=======================================================================\
    \nsha256rec: \
          \n=======================================================================\
          \nCurrent Folder : $current \
    \nTarget Folder  : $target"

  #GETS DEFAULT_USER, ASSUME'S YOU'RE USER 1000, IF 1000 DOESN'T EXIST SEARCHES 999, THEN 1001, 1002
  default_user=$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)
  if [ -z "$default_user" ]; then default_user=$(awk -v val=999 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1001 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1002 -F ":" '$3==val{print $1}' /etc/passwd); fi

  if [ "$(users | wc -l)" = "1" ]; then USER=$(users|awk '{print $1}'); else USER=$default_user;fi #not perfect but meh...

  #running rando_name in this very specific spot between USER detection and Permission detection, some interfers somehow with detection functions... 
  #the rando function placed underneath the user detection is somehow turning c=$current from the dir path to whatever rando_name puts out.

  #FIGURE OUT WHERE TO PUT HASH LIST
  hash_file="000_sha256sum_recurs_${target##*/}_d_$(date +%d-%m-20%y)_t_$(date +%H.%M).txt"
  if [ $(s_readonly "$current") -gt 0 -o $(w_denied "$current") -gt 0 ]; then if [ "$(whoami)" != root ]; then dest="/home/$(whoami)";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder."; else dest="/home/$USER";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently a Read-Only system. You can find the hash results in $USER's home folder.";fi; else dest="$current";echo -e "Output File    : $dest/$hash_file\n\n";echo "Results will be saved here.";fi



  #CAN REGULAR USER ACCESS TARGET DIR? ARE ALL IT'S SUBDIRS READABLE?
  if [ $(r_denied "$target") -gt 0 ]; then sudo=sudo; echo "Some folder were not read-able as a regular user. User elevation will be required.";fi

  #PERFORM RECURSIVE HASHING
  command=$($sudo find . -type f -not -type l -not -path "$arg1"  -not -path "$2"  -not -path "$3" -not -path "$4"  -not -path "$5"  -not -path "$6" -not -path "$7"  -not -path "$8"  -not -path "$9" |grep -v "\./000_sha"|sort|awk "{print \"$sudo sha256sum \\\"\"\$0}"|awk '{print $0"\""}'|tr '\n' ';')
  eval $command > "$dest/$hash_file"

  sha256sum "$dest/$hash_file"
  echo "Operation Length: $(stot) Seconds."
  echo -e  "======================================================================="



  if [ "$target" != "$current" ]; then cd "$current";fi


  exit
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  1. เมื่อคุณออกจากนาโนให้แน่ใจว่าออกจากสถานะที่ยกระดับโดยการป้อน:

    exit

ความคิดสุดท้าย

  1. วิธีนี้จะใช้งานได้หากคุณติดตั้ง bash แล้วเท่านั้น ฉันใช้ synthax สำหรับการจัดการสตริงย่อยที่ไม่ทำงานกับ sh, dash, ksh หรือ zsh คุณยังคงสามารถใช้เชลล์อื่น ๆ เป็นไดร์เวอร์รายวันของคุณได้ แต่ต้องทำการติดตั้ง bash

  2. รายการผลลัพธ์สามารถเปรียบเทียบกับเครื่องมือหลากหลายเช่น: (ในเทอร์มินัล) diff, sdiff (และกราฟิก) กระจาย, kdiff, winmerge

  3. ไฟล์ของฉันเรียงลำดับผลลัพธ์ตามเส้นทางเพื่อให้มนุษย์อ่านได้ง่ายขึ้น ฉันสังเกตุเห็นว่าคำสั่ง sort นั้นทำงานแตกต่างกันไปในแต่ละ distros ตัวอย่างเช่นในตัวอักษรแบบตัวพิมพ์ใหญ่ตัวหนึ่งมีความสำคัญมากกว่าตัวพิมพ์ใหญ่และตัวอักษรอื่นที่ไม่ใช่ สิ่งนี้มีผลต่อลำดับบรรทัดของไฟล์เอาต์พุตและอาจทำให้ไฟล์เปรียบเทียบยาก สิ่งนี้ไม่ควรนำเสนอปัญหาใด ๆ หากคุณใช้สคริปต์ใน distro เดียวกันเสมอ แต่อาจเกิดขึ้นได้หากรายการ hash ถูกสร้างขึ้นในสองสภาพแวดล้อมที่แตกต่างกัน วิธีนี้สามารถแก้ไขได้ง่ายโดยการเรียงลำดับไฟล์แฮชอีกครั้งเพื่อให้บรรทัดกลายเป็นคำสั่งโดยแฮชแทนที่จะเป็นพา ธ :

     cat 000_sha256sum_oldhashlist|sort> ./old
     cat 000_sha256sum_newhashlist|sort> ./new
     sha256sum ./old ./new; diff ./old ./new

บรรทัด shebang ที่มีประสิทธิภาพมากขึ้น#!/usr/bin/env bash- จะพบ Bash ในไดเรกทอรีอื่นเช่นกันเนื่องจากอาจมีการติดตั้งใน/ usr / binมากกว่า/ binตัวอย่างเช่นในขณะที่envมีแนวโน้มที่จะอยู่ใน/ usr / binตลอดเวลา เท่าที่ฉันสังเกตเห็น สิ่งที่ควรทราบก็คือเมื่อคุณต้องการ Bash คุณอาจใช้[[ blah-blah ]]นิพจน์แบบมีเงื่อนไขสองวงเล็บแทน[ blah-blah ]ตัวแปรแบบวงเล็บเดี่ยวทั่วไปที่มีความหลากหลายมากขึ้น
Anton Samsonov

ขอบคุณสำหรับคำแนะนำ ฉันเพิ่งค้นหา [เงื่อนไข [เสร็จสิ้น] พวกมันดูมีประโยชน์จริงๆ
thebunnyrules

ข้อกังวลเกี่ยวกับ SHA1 ที่ถูกบุกรุกนั้นไม่สามารถใช้งานได้จริงในกรณีของการเปรียบเทียบไฟล์หลังจากการคัดลอกเพื่อตรวจสอบความถูกต้อง โอกาสของไฟล์ที่เสียหายระหว่างการขนส่ง แต่ยังคงมี SHA1 เหมือนเดิมไม่มีจริง หากคุณสงสัยว่าผู้โจมตีอาจจะมีเวลาพอที่จะสร้างไฟล์ที่แตกต่างกันกับ SHA1 ชนแล้วใช้ SHA256 แต่สำหรับกรณีทั่วไปของการคัดลอกไฟล์ที่ overkill และช้ากว่า SHA1 หรือ MD5
Dan Dascalescu

คุณสามารถโต้แย้งตนเองได้ หากคุณกังวลเกี่ยวกับการทุจริตปกติ (ไม่เกี่ยวข้องกับการโจมตี) แสดงว่า sha1 นั้นเกินความจริง คุณสามารถได้ผลลัพธ์ที่เร็วขึ้นโดยใช้ md5 / crc32 ไม่ว่าจะในสถานการณ์ใด (การตรวจจับการงัดแงะหรือการทุจริต) sha1 นั้นไม่เหมาะสม โดยส่วนตัวแล้วฉันใช้รายการแฮชเหล่านี้สำหรับทั้งสองสถานการณ์และไม่ได้สังเกตเห็นประสิทธิภาพการทำงานที่รับรู้ได้ตั้งแต่ฉันอัปเกรดเป็น sha256 แต่ฉันไม่ได้ใช้เซิร์ฟเวอร์ขนาดใหญ่เช่นกัน เช่นเดียวกับที่ฉันกล่าวในคำตอบคุณมีอิสระที่จะใช้แฮชที่คุณต้องการโดยแทนที่คำสั่ง sha256sum ของฉันด้วยคำสั่งที่คุณต้องการ: sha1sum, md5sum, b2sum, crc32 ...
thebunnyrules

1

ดูเหมือนว่าจะใช้งานได้สำหรับฉัน:

find . \( -not -name . \) -type f -exec cat {} + | sha1sum

แก้ไข: นี่จะเพียง sha1sum ไฟล์ทั้งหมดที่มีอยู่ในต้นไม้ไดเรกทอรี หากมีการเปลี่ยนชื่อไดเรกทอรีจะไม่สามารถตรวจจับได้ อาจจะชอบ:

find . -exec sha1sum {} + 2>&1 | sha1sum

จะทำมัน เกี่ยวกับคำตอบเดียวกับที่อื่น ๆ แม้ว่า


1

เคล็ดลับอีกอย่างคือการใช้ tar เพื่อแฮชเนื้อหาของไฟล์ & ข้อมูลเมตา:

tar -cf - ./path/to/directory | sha1sum

เลวร้ายเกินไปที่ฉันมีเพียงหนึ่งคะแนน
166_MMX

1
สิ่งนี้ใช้ไม่ได้ tar รวมถึงการประทับเวลาสำหรับ OS บางระบบ (เช่น OSX) และ sha1sum จะแตกต่างกันในการรันแต่ละครั้ง
srossross

@rossross พูดอะไร นอกจากนี้หากคุณมี tar เวอร์ชั่นต่างกันในสองโฮสต์ผลลัพธ์จะแตกต่างกัน
Dan Dascalescu

1

โซลูชันที่รวดเร็วแข็งแกร่งและพกพาได้

แตกต่างจากโซลูชันอื่น ๆ บางส่วนที่เกี่ยวข้องtarโซลูชันด้านล่างนี้ทำงานบนเครื่องที่มียูทิลิตี้ Unix มาตรฐานและเร็วกว่าโซลูชันอื่น ๆ ทั้งหมดโดยการตรวจสอบแบบขนาน:

find . -type f | xargs -d'\n' -P0 -n1 md5sum | sort -k 2 | md5sum

เนื่องจากใช้การเรียงลำดับในตอนท้ายจึงไม่มีความคืบหน้าแบบเรียลไทม์ดังนั้นให้ปล่อยให้คำสั่งรัน

นี่คือสิ่งที่อาร์กิวเมนต์ทำ:

  • find . -type f ค้นหาไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันและไดเรกทอรีย่อย
  • xargs -d'\n'แยกเอาต์พุตของ find in lines (หากคุณคาดว่าจะมีไฟล์ที่มีบรรทัดใหม่ในไฟล์เหล่านั้นให้ทำตามปกติfind -print0 | xargs -0)
  • -P0 n1ทำงานmd5sumในกระบวนการแบบขนานโดยใช้จำนวนสูงสุดของกระบวนการที่เครื่องรองรับ (มัลติคอร์!)
  • sort -k 2เรียงลำดับตามฟิลด์ที่สองของmd5sumเอาต์พุตซึ่งเป็นพา ธ แบบเต็มไปยังแต่ละไฟล์ (อันแรกคือ MD5)
  • สุดท้ายจะmd5sumคำนวณ checksum ของรายการ checksum ของไฟล์ดังนั้นคุณจะได้รับ checksum ของไดเรกทอรีทั้งหมดในหนึ่งบรรทัดซึ่งคุณสามารถเปรียบเทียบการมองเห็นผ่านหน้าต่างเทอร์มินัลได้อย่างง่ายดาย

ก่อนที่คุณจะพูดว่า "MD5 ถูกโจมตี" โปรดทราบว่ารูปแบบการคุกคามของคุณคืออะไร คุณกำลังพยายามทำให้แน่ใจว่าไฟล์ที่คุณคัดลอกจากโฮสต์หรือดิสก์อื่นมาถึงหรือไม่? MD5 นั้นก็เพียงพอแล้วเนื่องจากโอกาสของไฟล์ที่เสียหายระหว่างการขนส่ง แต่การมี MD5 เดียวกันนั้นจะเป็นศูนย์ แต่ถ้าคุณมีความกลัวของผู้โจมตีมีเวลาในการเปลี่ยนไฟล์ที่มีหนึ่งที่แตกต่างกันกับการตรวจสอบชน, sha256sumการใช้งานแล้ว ข้อเสียคือฟังก์ชั่น SHA จะช้ากว่า MD5

ความคืบหน้า verbose เรียลไทม์

สุดท้ายหากคุณต้องการเห็นความคืบหน้าตามเวลาจริงให้แก้ไขไปป์ไลน์เพื่อใช้ไฟล์ชั่วคราวสำหรับเช็คซัม:

find . -type f | xargs -d\\n -P0 -n1 md5sum | tee /tmp/sums && sort -k 2 /tmp/sums | md5sum

(โปรดทราบว่าการเลื่อนไปsortทางขวาหลังจากใช้findงานไม่ได้จะเกิดขึ้นเนื่องจากการทำงานxargs -P0แบบขนานmd5sumและผลลัพธ์อาจไม่เป็นระเบียบ)

คำสั่งเวอร์ชันนี้ยังช่วยให้คุณสามารถแตก/tmp/sumsไฟล์สองไฟล์ (ตรวจสอบให้แน่ใจว่าเปลี่ยนชื่อไฟล์ที่สองหากอยู่ในเครื่องเดียวกัน) และดูว่าไฟล์ใดที่แตกต่างกัน


0

แทนที่จะมีไฟล์ขนาดมหึมาหนึ่งไฟล์ที่มีข้อมูลที่แฮชทั้งหมดฉันกำลังมองหาวิธีสร้างไฟล์ในแต่ละโฟลเดอร์ของทรี ฉันได้แรงบันดาลใจจากความคิดเห็นที่นี่ ฉันค่อนข้างซับซ้อนกว่าสิ่งที่โพสต์ที่นี่ ฉันใช้การหมุนไฟล์ แต่มันซับซ้อนน้อยที่สุดสำหรับผู้เล่นใหม่ รุ่นนี้จะมีมันเขียนทับผลรวมตรวจสอบเก่ากับใหม่ อาจเป็นการดีที่จะเก็บรุ่น 2-3 ขึ้นอยู่กับความถี่ที่คุณเรียกใช้และความต้องการของ 'ความลึก'

[user @ host bin] $ cat mkshaindir 
#! / bin / ประ
cd $ 1
sha512sum *> .sha512sum

[user @ host bin] $ find / var / tmp -type d -print0 | xargs -0 -i mkshaindir {}

โปรดทราบว่า mkshaindir สำหรับวัตถุประสงค์ของฉันเป็นองค์ประกอบแยกต่างหากเนื่องจากอาจมีความจำเป็นที่ฉันจะต้องทำการแฮชไฟล์ในโฟลเดอร์ใหม่หรือที่เพิ่งเปลี่ยนไป ทั้งหมดนี้สามารถรวมเข้ากับสคริปต์เดียวได้ถ้าต้องการ

ส่วนที่เหลือจะเป็นแบบฝึกหัดสำหรับผู้อ่าน


0

ตามคำตอบก่อนหน้า:

find ./path/to/directory -print0 | LC_ALL=C sort --zero-terminated | tar --create --no-recursion --null --files-from /dev/stdin --file /dev/stdout --verbose --numeric-owner | sha1sum

  • จัดเรียงที่มั่นคง
  • เจ้าของตัวเลขและรหัสกลุ่ม
  • ความคืบหน้าอย่างละเอียด
  • ชื่อไฟล์ที่ปลอดภัย

สิ่งนี้ไม่ทำงานในไดเรกทอรีที่คัดลอกซึ่งมีเพียงไฟล์เดียวและฉันสงสัยว่าเป็นเพราะฉันใช้ tar รุ่นเก่ากว่าเล็กน้อย (1.28) บนรีโมตโฮสต์เปรียบเทียบกับ 1.29 ในโฮสต์ท้องถิ่น แต่น่าเสียดายที่ tar 1.29 ยังไม่ได้รับการbackportedบน Xenial
Dan Dascalescu

0

@allquixoticคำตอบไม่ได้สร้างแฮชเดียวกันบนเครื่องที่แตกต่างกันซึ่งจะไม่ช่วยให้เราตรวจสอบและมีแฮชที่สม่ำเสมอ

บรรทัดfind . -type f \( -exec md5sum "$PWD"/{} \; \)ต่อไปนี้จะคืนค่าเอาต์พุตดังต่อไปนี้:

d41d8cd98f00b204e9800998ecf8427e  /home/helloWorld.c
24811012be8faa36c8f487bbaaadeb71  /home/helloMars.c

ดังนั้นเส้นทางจะแตกต่างกันในเครื่องที่แตกต่างกัน awk '{print $1}'จะช่วยให้เราได้รับคอลัมน์แรกซึ่งมีเฉพาะแฮชของไฟล์ ต่อมาเราต้องเรียงลำดับแฮชเหล่านั้นซึ่งคำสั่งซื้ออาจแตกต่างกันไปในเครื่องที่แตกต่างกันซึ่งอาจทำให้เรามีแฮชต่างกันหากมีไฟล์มากกว่าสองไฟล์


วิธีการแก้:

สำหรับ Mac:

find ./path/to/directory/ -type f \( -exec md5 -q  "$PWD"/{} \; \) | awk '{print $1}' | sort | md5

สำหรับ Linux:

find ./path/to/directory/ -type f \( -exec md5sum "$PWD"/{} \; \) | awk '{print $1}' | sort | md5sum | awk '{print $1}'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.