ปัญหาของฉัน (ในสคริปต์ด้วย#!/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' {} +