ปัญหาของฉัน (ในสคริปต์ด้วย#!/bin/sh
) มีดังนี้: ฉันพยายามตรวจสอบไฟล์ทั้งหมดในไดเรกทอรีเพื่อการเก็บถาวร ไฟล์ checksum (ในกรณีของฉัน sha1) ที่มีชื่อไฟล์ทั้งหมดควรอยู่ในไดเรกทอรีเดียวกัน ช่วยบอกว่าเรามีไดเรกทอรี~/test
พร้อมไฟล์f1
และf2
:
mkdir ~/test
cd ~/test
echo "hello" > f1
echo "world" > f2
ตอนนี้กำลังคำนวณ checksums ด้วย
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum
ทำตามที่ฉันต้องการทุกอย่างแสดงรายการไฟล์ทั้งหมดของไดเรกทอรีปัจจุบันเท่านั้นและคำนวณผลรวม sha1 (maxdepth อาจเปลี่ยนแปลงได้ในภายหลัง) เอาต์พุตบน STDOUT คือ:
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
น่าเสียดายที่เมื่อพยายามบันทึกไฟล์ลงในไฟล์ด้วย
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum > sums.sha1
ไฟล์ผลลัพธ์แสดงเช็กซัมสำหรับตัวมันเอง:
da39a3ee5e6b4b0d3255bfef95601890afd80709 sums.sha1
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
และดังนั้นจึงล้มเหลวในภายหลังshasum --check
เนื่องจากปัญหาที่ชัดเจนของการแก้ไขไฟล์เพิ่มเติมเมื่อบันทึกผลรวมสุดท้าย
ฉันมองไปรอบ ๆ และใช้การ-p
ตั้งค่าสถานะสำหรับxargs
ฉันพบว่ามันสร้างไฟล์เอาต์พุตก่อนที่จะดำเนินการคำสั่ง find ดังนั้นจึงพบไฟล์เพิ่มเติมและจะตรวจสอบ ...
ฉันรู้ว่าเป็นวิธีแก้ปัญหาฉันสามารถบันทึกการตรวจสอบไปยังสถานที่อื่น (ไดเรกทอรีชั่วคราวผ่านmktemp
) หรือยกเว้นในการค้นหาโดยเฉพาะ แต่ฉันต้องการที่จะเข้าใจว่าทำไมมันทำงานในแบบที่มัน - ซึ่งอยู่ในสายตาของฉันไม่มีประโยชน์ เช่นถ้าคำสั่งแรกจะตรวจสอบว่าไฟล์ที่ส่งออกอยู่บนดิสก์แล้วมันจะไม่ได้คำตอบที่ถูกต้อง ...
sh
จำเป็นต้องมีการเรียกใช้หลายครั้ง ทราบว่าคุณต้องโต้แย้งสำหรับก่อน$0
{}
tee
ได้หายไป? ฉันพยายามมันและทำงานดีฉันยังเก็บกด STDOUT 1>/dev/null
กับการเพิ่มของ มีบางอย่างผิดปกติกับคำตอบหรือเป็นข้อผิดพลาดหรือไม่?
xargs
ได้เป็นเชลล์ตัวเองที่สร้างไฟล์นี้เพราะก่อนที่คำสั่งใด ๆ จะถูกดำเนินการในตอนแรกเชลล์เปลี่ยนเส้นทางอินพุตเอาต์พุตและไพพ์ทั้งหมดดังนั้นเมื่อfind
เริ่มต้นไฟล์เอาต์พุตที่มีอยู่แล้ว ใช้-exec
แทน:find -maxdepth 1 -type f -exec sh -c 'shasum "$@" > sums.sha1' {} +