ดังนั้นเมื่อเร็ว ๆ tar
นี้ผมอยากจะทำเช่นนี้กับ การสอบสวนบางอย่างบ่งชี้ว่าเป็นเรื่องไร้สาระที่ฉันทำไม่ได้ ฉันคิดsplit --filter="cat >file; tar -r ..."
สิ่งแปลกประหลาดนี้ขึ้นมาแต่มันช้ามาก และยิ่งฉันอ่านเกี่ยวกับtar
เรื่องไร้สาระมากขึ้นเท่าไหร่
คุณเห็นtar
เป็นเพียงรายการที่ตัดแบ่ง ไฟล์องค์ประกอบจะไม่เปลี่ยนแปลงในทางใด ๆ - พวกเขาทั้งภายในเก็บถาวร แต่พวกเขาถูกปิดกั้นปิดที่ 512 ไบต์บล็อกขอบเขตและก่อนหน้านี้ทุกไฟล์มีส่วนหัว แค่นั้นแหละ. รูปแบบส่วนหัวนั้นง่ายมากเช่นกัน
tar
ดังนั้นฉันจึงเขียนของตัวเอง ผมเรียกมันว่า shitar
...
z() (IFS=0; printf '%.s\\0' $(printf "%.$(($1-${#2}))d"))
chk() (IFS=${IFS#??}; set -f; set -- $(
printf "$(fmt)" "$n" "$@" '' "$un" "$gn"
); IFS=; a="$*"; printf %06o "$(($(
while printf %d+ "'${a:?}"; do a=${a#?}; done 2>/dev/null
)0))")
fmt() { printf '%s\\'"${1:-n}" %s "${1:+$(z 99 "$n")}%07d" \
%07o %07o %011o %011o "%-${1:-7}s" ' 0' "${1:+$(z 99)}ustar " %s \
"${1:+$(z 31 "$un")}%s"
}
นั่นคือเนื้อสัตว์และมันฝรั่งจริงๆ มันเขียนส่วนหัวและคำนวณ chksum - ซึ่งพูดค่อนข้างเป็นส่วนที่ยากเท่านั้น มันไม่ustar
รูปแบบส่วนหัว ... บางที อย่างน้อยที่สุดมันจำลองสิ่งที่ GNU tar
คิดว่าเป็นustar
รูปแบบส่วนหัวไปยังจุดที่ไม่ได้บ่น และมีมากขึ้นมันก็เพียงว่าฉันไม่ได้จริงๆจับตัวมันยัง ที่นี่ฉันจะแสดงให้คุณ:
for f in 1 2; do echo hey > file$f; done
{ tar -cf - file[123]; echo .; } | tr \\0 \\n | grep -b .
0:file1 #filename - first 100 bytes
100:0000644 #octal mode - next 8
108:0001750 #octal uid,
116:0001750 #gid - next 16
124:00000000004 #octal filesize - next 12
136:12401536267 #octal epoch mod time - next 12
148:012235 #chksum - more on this
155: 0 #file type - gnu is weird here - so is shitar
257:ustar #magic string - header type
265:mikeserv #owner
297:mikeserv #group - link name... others shitar doesnt do
512:hey #512-bytes - start of file
1024:file2 #512 more - start of header 2
1124:0000644
1132:0001750
1140:0001750
1148:00000000004
1160:12401536267
1172:012236
1179: 0
1281:ustar
1289:mikeserv
1321:mikeserv
1536:hey
10240:. #default blocking factor 20 * 512
tar
ที่ ทุกอย่างเต็มไปด้วย\0
nulls ดังนั้นฉันจึงเปลี่ยนem
เป็น\n
ewlines เพื่อให้อ่านง่ายขึ้น และshitar
:
#the rest, kind of, calls z(), fmt(), chk() + gets $mdata and blocks w/ dd
for n in file[123]
do d=$n; un=$USER; gn=$(id --group --name)
set -- $(stat --printf "%a\n%u\n%g\n%s\n%Y" "$n")
printf "$(fmt 0)" "$n" "$@" "$(chk "$@")" "$un" "$gn"
printf "$(z $((512-298)) "$gn")"; cat "$d"
printf "$(x=$(($4%512));z $(($4>512?($x>0?$x:512):512-$4)))"
done |
{ dd iflag=fullblock conv=sync bs=10240 2>/dev/null; echo .; } |
tr \\0 \\n | grep -b .
เอาท์พุท
0:file1 #it's the same. I shortened it.
100:0000644 #but the whole first file is here
108:0001750
116:0001750
124:00000000004
136:12401536267
148:012235 #including its checksum
155: 0
257:ustar
265:mikeserv
297:mikeserv
512:hey
1024:file2
...
1172:012236 #and file2s checksum
...
1536:hey
10240:.
ฉันพูดแบบนั้นเพราะนั่นไม่ใช่shitar
จุดประสงค์ - tar
ทำอย่างนั้นเรียบร้อยแล้ว ฉันแค่อยากจะแสดงวิธีการทำงาน - chksum
ซึ่งหมายความว่าฉันจะต้องสัมผัสกับ ถ้าไม่ใช่เพราะสิ่งนั้นฉันก็แค่dd
ถอดหัวtar
ไฟล์ออกแล้วทำมัน แม้บางครั้งอาจใช้งานได้ แต่มันก็ยุ่งเหยิงเมื่อมีสมาชิกหลายคนในที่เก็บถาวร ถึงกระนั้น chksum ก็ง่ายจริงๆ
ก่อนให้มัน 7 ช่องว่าง - (ซึ่งเป็นสิ่งที่แปลก GNU ผมคิดว่าเป็นสเปคกล่าวว่า 8 แต่สิ่งที่ - สับเป็นสับ) จากนั้นเพิ่มค่าฐานแปดของทุกไบต์ในส่วนหัว นั่นคือ chksum ของคุณ ดังนั้นคุณต้องมีเมทาดาทาไฟล์ก่อนที่จะทำส่วนหัวหรือคุณไม่มี chksum และนั่นเป็นที่ustar
เก็บถาวร
ตกลง. ตอนนี้สิ่งที่ควรทำ:
cd /tmp; mkdir -p mnt
for d in 1 2 3
do fallocate -l $((1024*1024*500)) disk$d
lp=$(sudo losetup -f --show disk$d)
sync
sudo mkfs.vfat -n disk$d "$lp"
sudo mount "$lp" mnt
echo disk$d file$d | sudo tee mnt/file$d
sudo umount mnt
sudo losetup -d "$lp"
done
นั่นทำให้ดิสก์อิมเมจขนาด 500M สามรูปแบบและประกอบเข้าด้วยกันและเขียนไฟล์ไปยังแต่ละรูป
for n in disk[123]
do d=$(sudo losetup -f --show "$n")
un=$USER; gn=$(id --group --name)
set -- $(stat --printf "%a\n%u\n%g\n$(lsblk -bno SIZE "$d")\n%Y" "$n")
printf "$(fmt 0)" "$n" "$@" "$(chk "$@")" "$un" "$gn"
printf "$(z $((512-298)) "$gn")"
sudo cat "$d"
sudo losetup -d "$d"
done |
dd iflag=fullblock conv=sync bs=10240 2>/dev/null |
xz >disks.tar.xz
หมายเหตุ - อุปกรณ์บล็อกที่เห็นได้ชัดจะปิดกั้นอย่างถูกต้องเสมอ ค่อนข้างมีประโยชน์
นั่นคือเนื้อหาของแฟ้มอุปกรณ์ดิสก์ในสตรีมและท่อออกไปtar
xz
ls -l disk*
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk1
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk2
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk3
-rw-r--r-- 1 mikeserv mikeserv 229796 Sep 3 01:05 disks.tar.xz
ตอนนี้ช่วงเวลาแห่งความจริง ...
xz -d <./disks.tar.xz| tar -tvf -
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk1
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk2
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk3
ไชโย! สกัด ...
xz -d <./disks.tar.xz| tar -xf - --xform='s/[123]/1&/'
ls -l disk*
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk1
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk11
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk12
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk13
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk2
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk3
-rw-r--r-- 1 mikeserv mikeserv 229796 Sep 3 01:05 disks.tar.xz
เปรียบเทียบ ...
cmp disk1 disk11 && echo yay || echo shite
yay
และภูเขา ...
sudo mount disk13 mnt
cat mnt/*
disk3 file3
ในกรณีนี้ก็shitar
โอเคฉันเดา ฉันไม่อยากทำทุกสิ่งที่ไม่ดี แต่ฉันจะบอกว่า - อย่าทำบรรทัดใหม่ในชื่อไฟล์อย่างน้อยที่สุด
นอกจากนี้คุณยังสามารถทำ - และอาจควรพิจารณาทางเลือกที่ผมเคยนำเสนอ -this squashfs
กับ ไม่เพียง แต่คุณจะได้รับไฟล์เก็บถาวรเดียวที่สร้างจากสตรีมเท่านั้น แต่ยังmount
สามารถสร้างขึ้นในเคอร์เนลได้ด้วยvfs
:
จากpseudo-file.example :
# Copy 10K from the device /dev/sda1 into the file input. Ordinarily
# Mksquashfs given a device, fifo, or named socket will place that special file
# within the Squashfs filesystem, this allows input from these special
# files to be captured and placed in the Squashfs filesystem.
input f 444 root root dd if=/dev/sda1 bs=1024 count=10
# Creating a block or character device examples
# Create a character device "chr_dev" with major:minor 100:1 and
# a block device "blk_dev" with major:minor 200:200, both with root
# uid/gid and a mode of rw-rw-rw.
chr_dev c 666 root root 100 1
blk_dev b 666 0 0 200 200
คุณอาจใช้btrfs (send|receive)
สตรีมซับวูฟเฟอร์ออกเป็นคอมเพรสเซอร์แบบใดก็ได้ที่stdin
คุณชอบ ซับโวลูมนี้ไม่จำเป็นต้องมีอยู่ก่อนที่คุณจะตัดสินใจใช้มันเป็นคอนเทนเนอร์บีบอัดแน่นอน
ยังเกี่ยวกับsquashfs
...
ฉันไม่เชื่อว่าฉันกำลังทำเรื่องนี้ นี่คือตัวอย่างง่ายๆ:
cd /tmp; mkdir ./emptydir
mksquashfs ./emptydir /tmp/tmp.sfs -p \
'file f 644 mikeserv mikeserv echo "this is the contents of file"'
Parallel mksquashfs: Using 6 processors
Creating 4.0 filesystem on /tmp/tmp.sfs, block size 131072.
[==================================================================================|] 1/1 100%
Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 131072
compressed data, compressed metadata, compressed fragments,...
###...
###AND SO ON
###...
echo '/tmp/tmp.sfs /tmp/imgmnt squashfs loop,defaults,user 0 0'|
sudo tee -a /etc/fstab >/dev/null
mount ./tmp.sfs
cd ./imgmnt
ls
total 1
-rw-r--r-- 1 mikeserv mikeserv 29 Aug 20 11:34 file
cat file
this is the contents of file
cd ..
umount ./imgmnt
นั่นเป็นเพียงแบบอินไลน์อาร์กิวเมนต์สำหรับการ-p
mksquash
คุณสามารถระบุไฟล์ที่มีไฟล์ได้-pf
มากเท่าที่คุณต้องการ รูปแบบนั้นง่าย - คุณกำหนดชื่อ / พา ธ ของไฟล์เป้าหมายในระบบไฟล์ของไฟล์เก็บถาวรใหม่คุณให้โหมดและเจ้าของจากนั้นคุณจะบอกว่ากระบวนการใดที่จะดำเนินการและอ่าน stdout จาก คุณสามารถสร้างได้มากเท่าที่คุณต้องการ - และคุณสามารถใช้ LZMA, GZIP, LZ4, XZ ... hmm มีรูปแบบการบีบอัดมากกว่าที่คุณต้องการ cd
และผลลัพธ์ที่ได้คือที่เก็บที่คุณ
เพิ่มเติมเกี่ยวกับรูปแบบที่:
แน่นอนว่านี่ไม่ใช่แค่ไฟล์เก็บถาวรเท่านั้น แต่เป็นอิมเมจระบบไฟล์บีบอัดที่ mountable ได้ รูปแบบของมันคือลีนุกซ์เคอร์เนล - เป็นระบบไฟล์เคอร์เนลที่รองรับวานิลลา ด้วยวิธีนี้มันเป็นเรื่องธรรมดาเหมือนเคอร์เนลวานิลลา ดังนั้นถ้าคุณบอกฉันว่าคุณกำลังใช้ระบบวานิลลาลินุกซ์ซึ่งtar
ไม่ได้ติดตั้งโปรแกรมฉันจะสงสัย - แต่ฉันอาจจะเชื่อคุณ แต่ถ้าคุณบอกฉันว่าคุณกำลังใช้ระบบวานิลลาลินุกซ์ซึ่งsquashfs
ระบบไฟล์ไม่รองรับฉันจะไม่เชื่อคุณ