如何将多个 tar 依次写入磁带?

如何将多个 tar 依次写入磁带?

我正在尝试将多个目录写入磁带。每个目录有一个 tar 命令。

所以我有以下示例文件/目录结构:

user@host1:~/temp/original % find .
.
./foo1
./foo1/foo1.a
./foo1/foo1.b
./foo1/foo1.c
./foo1/foo1.1
./foo2
./foo2/foo2.a
./foo2/foo2.b
./foo2/foo2.c
./foo2/foo2.2
./foo3
./foo3/foo3.a
./foo3/foo3.b
./foo3/foo3.c
./foo3/foo3.3

我倒带并擦除磁带,我希望这就像使用空白磁带一样。

user@host1:~/temp/original % mt -f /dev/sa0 rewind
user@host1:~/temp/original % mt -f /dev/sa0 erase
user@host1:~/temp/original % mt -f /dev/sa0 rewind
user@host1:~/temp/original % mt -f /dev/sa0 status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   0     Calc Record Number: 0
Residual:    0  Reported File Number:   0 Reported Record Number: 0
Flags: BOP

然后我想用三个 tar 命令写入三个 tar 文件(我认为当它们存储到磁带时被称为文件)。每个目录(foo1、foo2 和 foo3)一个命令。所以我这样做:

user@host1:~/temp/original % tar cvf /dev/nsa0 foo1
a foo1
a foo1/foo1.a
a foo1/foo1.b
a foo1/foo1.c
a foo1/foo1.1
user@host1:~/temp/original % tar cvf /dev/nsa0 foo2
a foo2
a foo2/foo2.a
a foo2/foo2.b
a foo2/foo2.c
a foo2/foo2.2
user@host1:~/temp/original % tar cvf /dev/nsa0 foo3
a foo3
a foo3/foo3.a
a foo3/foo3.b
a foo3/foo3.c
a foo3/foo3.3

正如我一直在使用的那样,/dev/nsa0我希望磁带中存储三个 tar 文件。

现在我想将磁带中的三个文件恢复到另一个目录中:

user@host1:~/temp/original % cd ../backup/
user@host1:~/temp/backup % mt -f /dev/sa0 rewind
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo1/
x foo1/foo1.a
x foo1/foo1.b
x foo1/foo1.c
x foo1/foo1.1
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo2/
x foo2/foo2.a
x foo2/foo2.b
x foo2/foo2.c
x foo2/foo2.2
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo3/
x foo3/foo3.a
x foo3/foo3.b
x foo3/foo3.c
x foo3/foo3.3
user@host1:~/temp/backup % mt -f /dev/nsa0 status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   2     Calc Record Number: 1
Residual:    0  Reported File Number:   2 Reported Record Number: 5
Flags: None

为什么我必须输入两次tar xvf /dev/nsa0才能提取foo2and foo3

如果我尝试在磁带末尾添加另一个目录,我会执行以下操作:

user@host1:~/temp/original % mt -f /dev/nsa0 eom
user@host1:~/temp/original % tar cvf /dev/nsa0 foo4
a foo4
a foo4/foo4.a
a foo4/foo4.b
a foo4/foo4.c
a foo4/foo4.4
user@host1:~/temp/original % cd ..
user@host1:~/temp % cd backup/
user@host1:~/temp/backup % mt -f /dev/nsa0 rewind
user@host1:~/temp/backup % mt -f /dev/nsa0 fsf 3
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % 

为什么foo4提取不出来?

作为附加测试,我弹出磁带,重新插入它并尝试提取四个目录,这就是我必须做的:

user@host1:~/temp/backup % mt -f /dev/nsa0 offline
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo1/
x foo1/foo1.a
x foo1/foo1.b
x foo1/foo1.c
x foo1/foo1.1
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo2/
x foo2/foo2.a
x foo2/foo2.b
x foo2/foo2.c
x foo2/foo2.2
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo3/
x foo3/foo3.a
x foo3/foo3.b
x foo3/foo3.c
x foo3/foo3.3
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo4/
x foo4/foo4.a
x foo4/foo4.b
x foo4/foo4.c
x foo4/foo4.4

为什么我必须重复 tar 命令,在foo2和 的 情况下重复两次foo3,在 的情况下重复三次foo4

我正在使用 FreeBSD12.1 和 IBM DDS4 (STD2401LW / Tc4200-236) SCSI 磁带驱动器。

编辑> 按照 schily 的回答,我可以按顺序提取 tar 文件。唯一剩下的问题是理解为什么mt eom稍后添加foo4tar 文件仍然需要两个mt fsf而不是一个。

重新插入磁带后:

user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo1/
x foo1/foo1.a
x foo1/foo1.b
x foo1/foo1.c
x foo1/foo1.1
user@host1:~/temp/backup % mt fsf
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo2/
x foo2/foo2.a
x foo2/foo2.b
x foo2/foo2.c
x foo2/foo2.2
user@host1:~/temp/backup % mt fsf
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo3/
x foo3/foo3.a
x foo3/foo3.b
x foo3/foo3.c
x foo3/foo3.3
user@host1:~/temp/backup % mt fsf
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo4/
x foo4/foo4.a
x foo4/foo4.b
x foo4/foo4.c
x foo4/foo4.4
user@host1:~/temp/backup %

编辑> 这是mt status在允许提取的位置处返回的内容foo4。插入磁带后立即执行命令:

user@host1:~/temp/backup % rm -rf *
user@host1:~/temp/backup % mt status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   0     Calc Record Number: 0
Residual:    0  Reported File Number:   0 Reported Record Number: 0
Flags: BOP
user@host1:~/temp/backup % echo $TAPE
/dev/nsa0
user@host1:~/temp/backup % mt fsf 4
user@host1:~/temp/backup % mt status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   4     Calc Record Number: 0
Residual:    0  Reported File Number:   4 Reported Record Number: 7
Flags: None
user@host1:~/temp/backup % tar xv
x foo4/
x foo4/foo4.a
x foo4/foo4.b
x foo4/foo4.c
x foo4/foo4.4
user@host1:~/temp/backup % 

答案1

该行为与磁带驱动程序的 EOF 处理有关。

此处理因操作系统而异,阅读相关的 Solaris 手册页可能会有所帮助:

http://schillix.sourceforge.net/man/man7i/mtio.7i.html

这解释了 Solaris 处理和旧 BSD 行为之间的差异。

根据这个解释,我预计旧的 BSD 行为会导致 EOF 情况后的读取跳过文件标记并从磁带上的下一个文件返回第一条记录。这似乎正是您所期望的。

似乎在 BSD 上观察到的行为介于记录的 SVr4 行为和旧的 BSD 行为之间,但我猜想有一种方法可以使事情在 Solaris 和当前的 BSD 上都工作:

  • 调用 tar 读取第一个磁带文件

  • 之后,磁带位于第一个磁带文件的末尾,即文件标记之前...

  • 调用mt fsf跳过文件标记

  • 调用 tar 读取磁带上的下一个文件。

从其余的讨论来看,FreeBSD 似乎会在mt rewind应用写入操作后调用 when 写入一个附加文件标记。

该命令mt eom将把磁带定位在最终双文件标记之后,并且当发生另一个写入操作时,这种情况发生在双文件标记之后,从而在最终写入之前产生空磁带文件。

包含三个文件的磁带如下所示:

data1 FILEMARK data2 FILEMARK data3 FILEMARK FILEMARK

如果您想附加第四个磁带文件,您需要调用:

mt fsf 3

将磁带定位在第三个文件标记之后。如果您随后开始写入,这将覆盖第四个文件标记,如果您再次倒带,则会出现以下磁带布局:

data1 FILEMARK data2 FILEMARK data3 FILEMARK data4 FILEMARK FILEMARK

答案2

我从未使用过磁带和 tar,但要附加到 tar 存档 tar 需要重写包含归零字节的最后一条记录,这表明存档的结尾以及下一个存档头。因此,如果您的磁带不可查找,您可能必须每次倒带,让 tar 读取该记录,然后覆盖它。

另外,在 GNU tar 中,用于附加的开关是-r而不是-c.

如果您仅将 tar 文件一个接一个地连接起来,GNU tar 还具有开关-i(在提取时),以便它读取归档文件的末尾,直到 EOF(在磁带设备的情况下)可以不可以这是一个明智的想法 - 如果 tar 在最后一个存档的末尾遇到旧数据,它可能会尝试提取它,或者更糟糕的是运气好并找到一个完全对齐的旧存档......)

我使用该-i开关通过管道传递多个 tar 档案,所以对我来说这不是问题。这同样适用于在末尾抛出 EOF 的普通文件。

相关内容