在OP 发表评论后,我发现/dev/stdout
即使在禁用缓冲后也会提供 10 KiB 的块,但-
不会。为什么是这样?man tar
我在nor中找不到与此相关的任何信息man stdout
。
请注意,/dev/stdout
转到00002800
,而不是000000a1
。输出是正确的,除了用空字节填充。
> mkdir -p /tmp/747613
> cd /tmp/747613
> echo 747613 > file.txt
> tar czf /tmp/archive_tgz .
> hd /tmp/archive_tgz
00000000 1f 8b 08 00 00 00 00 00 00 03 ed d1 41 0a c2 30 |............A..0|
00000010 10 85 e1 ac 3d 45 4e 90 66 9a 49 72 9e 2e 22 08 |....=EN.f.Ir..".|
00000020 ea a2 46 f0 f8 a6 8b a2 9b 76 21 04 11 ff 6f f3 |..F......v!...o.|
00000030 20 33 90 81 e7 06 d3 9d 6f 72 8e 4b 4a 8e fe 3d | 3......or.KJ..=|
00000040 57 46 54 43 6c 8f 69 6c 7b 22 da c6 36 f6 3f cd |WFTCl.il{"..6.?.|
00000050 98 fb ad 4e b3 b5 2d cb 7c 9d 2e 65 7b 6f 7f fe |...N..-.|..e{o..|
00000060 a3 dc 70 3c 9d 8b ab 8f da ef 8f a5 e0 94 74 a7 |..p<..........t.|
00000070 ff bc f6 2f 41 a5 f5 1f 64 14 63 7d bf 93 5e fe |.../A...d.c}..^.|
00000080 bc ff ac 39 49 38 7c fb 0c 00 00 00 00 00 00 00 |...9I8|.........|
00000090 00 00 00 00 00 00 1f 78 02 88 2a 27 ac 00 28 00 |.......x..*'..(.|
*
000000a1
> tar czf /dev/stdout . | hd
00000000 1f 8b 08 00 00 00 00 00 00 03 ed d1 41 0a c2 30 |............A..0|
00000010 10 85 e1 ac 3d 45 4e 90 66 9a 49 72 9e 2e 22 08 |....=EN.f.Ir..".|
00000020 ea a2 46 f0 f8 a6 8b a2 9b 76 21 04 11 ff 6f f3 |..F......v!...o.|
00000030 20 33 90 81 e7 06 d3 9d 6f 72 8e 4b 4a 8e fe 3d | 3......or.KJ..=|
00000040 57 46 54 43 6c 8f 69 6c 7b 22 da c6 36 f6 3f cd |WFTCl.il{"..6.?.|
00000050 98 fb ad 4e b3 b5 2d cb 7c 9d 2e 65 7b 6f 7f fe |...N..-.|..e{o..|
00000060 a3 dc 70 3c 9d 8b ab 8f da ef 8f a5 e0 94 74 a7 |..p<..........t.|
00000070 ff bc f6 2f 41 a5 f5 1f 64 14 63 7d bf 93 5e fe |.../A...d.c}..^.|
00000080 bc ff ac 39 49 38 7c fb 0c 00 00 00 00 00 00 00 |...9I8|.........|
00000090 00 00 00 00 00 00 1f 78 02 88 2a 27 ac 00 28 00 |.......x..*'..(.|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002800
> # Even with buffering disabled
> stdbuf -i0 -o0 -e0 tar czf /dev/stdout . | stdbuf -i0 -o0 -e0 hd
00000000 1f 8b 08 00 00 00 00 00 00 03 ed d1 41 0a c2 30 |............A..0|
00000010 10 85 e1 ac 3d 45 4e 90 66 9a 49 72 9e 2e 22 08 |....=EN.f.Ir..".|
00000020 ea a2 46 f0 f8 a6 8b a2 9b 76 21 04 11 ff 6f f3 |..F......v!...o.|
00000030 20 33 90 81 e7 06 d3 9d 6f 72 8e 4b 4a 8e fe 3d | 3......or.KJ..=|
00000040 57 46 54 43 6c 8f 69 6c 7b 22 da c6 36 f6 3f cd |WFTCl.il{"..6.?.|
00000050 98 fb ad 4e b3 b5 2d cb 7c 9d 2e 65 7b 6f 7f fe |...N..-.|..e{o..|
00000060 a3 dc 70 3c 9d 8b ab 8f da ef 8f a5 e0 94 74 a7 |..p<..........t.|
00000070 ff bc f6 2f 41 a5 f5 1f 64 14 63 7d bf 93 5e fe |.../A...d.c}..^.|
00000080 bc ff ac 39 49 38 7c fb 0c 00 00 00 00 00 00 00 |...9I8|.........|
00000090 00 00 00 00 00 00 1f 78 02 88 2a 27 ac 00 28 00 |.......x..*'..(.|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002800
> # Works fine (- means stdout)
> tar czf - . | hd
00000000 1f 8b 08 00 00 00 00 00 00 03 ed d1 41 0a c2 30 |............A..0|
00000010 10 85 e1 ac 3d 45 4e 90 66 9a 49 72 9e 2e 22 08 |....=EN.f.Ir..".|
00000020 ea a2 46 f0 f8 a6 8b a2 9b 76 21 04 11 ff 6f f3 |..F......v!...o.|
00000030 20 33 90 81 e7 06 d3 9d 6f 72 8e 4b 4a 8e fe 3d | 3......or.KJ..=|
00000040 57 46 54 43 6c 8f 69 6c 7b 22 da c6 36 f6 3f cd |WFTCl.il{"..6.?.|
00000050 98 fb ad 4e b3 b5 2d cb 7c 9d 2e 65 7b 6f 7f fe |...N..-.|..e{o..|
00000060 a3 dc 70 3c 9d 8b ab 8f da ef 8f a5 e0 94 74 a7 |..p<..........t.|
00000070 ff bc f6 2f 41 a5 f5 1f 64 14 63 7d bf 93 5e fe |.../A...d.c}..^.|
00000080 bc ff ac 39 49 38 7c fb 0c 00 00 00 00 00 00 00 |...9I8|.........|
00000090 00 00 00 00 00 00 1f 78 02 88 2a 27 ac 00 28 00 |.......x..*'..(.|
*
000000a1
行为上的差异来自
tar
:写入时,它应用“阻塞因子”,默认情况下使用 10240 字节的记录(十六进制为 2800)。gzip
即使在压缩时也会发生这种情况,这就是为什么某些 tarball 在提取时会产生错误消息的原因。当将存档写入常规文件或标准输出时,该行为在存档末尾被禁用(尽管手册说不是)。写入时
/dev/stdout
,tar
相信它正在写入设备,并应用其阻塞因子。您可以通过更改阻塞因子来验证这一点: