โดยทั่วไปสิ่งที่คุณต้องการคือความเป็นไปได้ในการไพพ์ไฟล์ลงใน tar และ "lop" ด้านหน้าตามที่คุณไป
ใน StackOverflow มีคนถามวิธีตัดทอนไฟล์ที่ด้านหน้าแต่ดูเหมือนว่าเป็นไปไม่ได้ คุณยังสามารถเติมจุดเริ่มต้นของไฟล์ด้วยศูนย์ในวิธีพิเศษเพื่อให้ไฟล์กลายเป็นไฟล์กระจัดกระจายแต่ฉันไม่ทราบวิธีการทำเช่นนี้ เราสามารถตัดปลายของไฟล์ได้ แต่ tar จำเป็นต้องอ่านไฟล์เก็บถาวรไปข้างหน้าไม่ใช่ถอยหลัง
โซลูชันที่ 1
ระดับของการอ้อมจะแก้ปัญหาทุกปัญหา ขั้นแรกให้ย้อนกลับไฟล์ในตำแหน่งจากนั้นอ่านย้อนหลัง (ซึ่งจะส่งผลให้อ่านไฟล์ต้นฉบับไปข้างหน้า) และตัดส่วนท้ายของไฟล์ที่กลับด้านในขณะที่คุณไป
คุณจะต้องเขียนโปรแกรม (c, python, อะไรก็ตาม) เพื่อแลกเปลี่ยนจุดเริ่มต้นและจุดสิ้นสุดของไฟล์, การแบ่งข้อมูลตามกลุ่มและจากนั้นไพพ์ชิ้นส่วนเหล่านี้เพื่อ tar ในขณะที่ตัดทอนไฟล์ทีละชิ้น นี่เป็นพื้นฐานสำหรับโซลูชัน 2 ซึ่งอาจใช้งานง่ายกว่า
โซลูชันที่ 2
อีกวิธีหนึ่งคือการแยกไฟล์เป็นชิ้นเล็ก ๆ ในตำแหน่งแล้วลบชิ้นเหล่านั้นเมื่อเราแยกไฟล์ออก รหัสด้านล่างมีขนาดก้อนละหนึ่งเมกะไบต์ปรับขึ้นอยู่กับความต้องการของคุณ ใหญ่กว่าเร็วกว่า แต่จะกินพื้นที่ระหว่างกลางมากขึ้นเมื่อทำการแยกและระหว่างการแยก
แยกไฟล์ archive.tar:
archive="archive.tar"
chunkprefix="chunk_"
# 1-Mb chunks :
chunksize=1048576
totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
# Print current chunk number, so we know it is still running.
echo -n "$currentchunk "
offset=$((currentchunk*chunksize))
# Copy end of $archive to new file
tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
# Chop end of $archive
truncate -s $offset "$archive"
currentchunk=$((currentchunk-1))
done
ไพพ์ไฟล์เหล่านั้นลงใน tar (โปรดทราบว่าเราต้องการตัวแปร chunkprefix ในเทอร์มินัลที่สอง):
mkfifo fifo
# In one terminal :
(while true; do cat fifo; done) | tar -xf -
# In another terminal :
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done > fifo
# When second terminal has finished :
# flush caches to disk :
sync
# wait 5 minutes so we're sure tar has consumed everything from the fifo.
sleep 300
rm fifo
# And kill (ctrl-C) the tar command in the other terminal.
เนื่องจากเราใช้การตั้งชื่อไปป์ ( mkfifo fifo
) คุณไม่จำเป็นต้องไปที่ชิ้นส่วนทั้งหมดพร้อมกัน สิ่งนี้มีประโยชน์หากคุณมีพื้นที่ จำกัด จริงๆ คุณสามารถทำตามขั้นตอนต่อไปนี้:
- ย้ายพูดชิ้นขนาด 10Gb สุดท้ายไปยังดิสก์อื่น
- เริ่มการสกัดด้วยชิ้นที่คุณยังมี
- เมื่อ
while [ -e … ]; do cat "$chunk…; done
ลูปเสร็จสิ้น (เทอร์มินัลที่สอง):
- อย่าหยุด
tar
คำสั่งอย่าลบ Fifo (เทอร์มินัลแรก) แต่คุณสามารถรันได้sync
ในกรณีที่
- ย้ายไฟล์ที่แตกแล้วซึ่งคุณรู้ว่าสมบูรณ์แล้ว (tar ไม่รอจนกว่าข้อมูลจะเสร็จสิ้นการแยกไฟล์เหล่านี้) ไปยังดิสก์อื่น
- ย้ายชิ้นส่วนที่เหลือกลับไป
- ทำการแยกต่อโดยรัน
while [ -e … ]; do cat "$chunk…; done
บรรทัดอีกครั้ง
ของหลักสูตรนี้คือทั้งหมดแฟชั่น Voltigeคุณจะต้องการที่จะตรวจสอบทุกอย่างก็โอเคในเก็บหุ่นแรกเพราะถ้าคุณทำผิดพลาดแล้วลาข้อมูล
คุณจะไม่มีทางรู้ว่าเทอร์มินัลตัวแรก ( tar
) ได้ทำการประมวลผลเนื้อหาของ Fifo จริงหรือไม่ดังนั้นถ้าคุณต้องการคุณสามารถรันสิ่งนี้แทนได้ แต่คุณไม่มีความเป็นไปได้ที่จะแลกเปลี่ยนชิ้นส่วนกับดิสก์อื่นอย่างราบรื่น:
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done | tar -xf -
คำปฏิเสธ
โปรดทราบว่าเพื่อให้การทำงานทั้งหมดเชลล์หางและตัดของคุณต้องจัดการกับจำนวนเต็ม 64- บิตอย่างถูกต้อง (คุณไม่จำเป็นต้องใช้คอมพิวเตอร์ 64 บิตหรือระบบปฏิบัติการสำหรับสิ่งนั้น) เหมืองแร่ไม่ แต่ถ้าคุณเรียกใช้สคริปต์ดังกล่าวข้างต้นในระบบโดยไม่ต้องการเหล่านี้คุณจะหลวมข้อมูลทั้งหมดใน archive.tar
และไม่ว่าในกรณีใด ๆ ก็ตามนอกจากสิ่งที่ผิดพลาดคุณจะสูญเสียข้อมูลทั้งหมดในไฟล์เก็บถาวรตามเดิมดังนั้นโปรดตรวจสอบให้แน่ใจว่าคุณได้สำรองข้อมูลของคุณแล้ว