# 练习 22：文件系统：移动数据，`tar`，`dd`

> 原文：[Exercise 22. Filesystems: moving data around: tar, dd](https://archive.fo/JSknE)

> 译者：[飞龙](https://github.com/wizardforcel)

> 协议：[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)

> 自豪地采用[谷歌翻译](https://translate.google.cn/)

现在是时候自己看看了，Linux 中的所有东西只是一个文件。

这个练习是一个很大的练习，但是看看你学到了什么。完成之后，在`man`中查看所有故意不解释的程序参数，，并试图自己解释每个命令的作用。

现在你将学习如何玩转数据。

## 这样做

```
 1: tar -czvf root.tgz /opt/root/
 2: tar -tzvf root.tgz
 3: cd /tmp
 4: tar -zxvf ~/root.tgz
 5: ls -al
 6: dd_if=$(mount | grep /tmp | cut -d ' ' -f 1) && echo $dd_if
 7: sudo dd if=$dd_if of=~/tmp.img bs=10M
 8: cd && ls -alh
 9: sudo losetup /dev/loop1 ~/tmp.img && sudo mount /dev/loop1 /mnt/
10: ls -al /mnt
11: sudo umount /mnt && sudo losetup -d /dev/loop1
12: sudo umount $dd_if && sudo mkfs.ext3 $dd_if
13: new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid
14: grep '/tmp' /etc/fstab
15: sed "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab
```

现在使用`sudo tune2fs -l`和`sudo blkid`检查输出。如果`/etc/fstab`中的 UUID 替换看起来正常，执行实际的替换。

```
16: sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab
17: sudo mount -a && ls /tmp
18: sudo umount /tmp && pv ~/tmp.img | sudo dd of=$dd_if bs=10M
19: new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid
20: sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab
21: sudo mount -a
22: rm -v tmp.img
```

输入`y`并按下`<ENTER>`。

## 你会看到什么

```
user1@vm1:~$ tar -czvf root.tgz /opt/root/
tar: Removing leading '/' from member names
/opt/root/
/opt/root/bin/
/opt/root/bin/bash
/opt/root/lib64/
/opt/root/lib64/ld-linux-x86-64.so.2
/opt/root/lib/
/opt/root/lib/libdl.so.2
/opt/root/lib/libncurses.so.5
/opt/root/lib/libc.so.6
user1@vm1:~$ tar -tzvf root.tgz
drwxr-xr-x root/root         0 2012-07-05 03:14 opt/root/
drwxr-xr-x root/root         0 2012-07-05 03:14 opt/root/bin/
-rwxr-xr-x root/root    926536 2012-07-05 03:14 opt/root/bin/bash
drwxr-xr-x root/root         0 2012-07-05 03:14 opt/root/lib64/
-rwxr-xr-x root/root    128744 2012-07-05 03:14 opt/root/lib64/ld-linux-x86-64.so.2
drwxr-xr-x root/root         0 2012-07-05 03:14 opt/root/lib/
-rw-r--r-- root/root     14696 2012-07-05 03:14 opt/root/lib/libdl.so.2
-rw-r--r-- root/root    286776 2012-07-05 03:14 opt/root/lib/libncurses.so.5
-rwxr-xr-x root/root   1437064 2012-07-05 03:14 opt/root/lib/libc.so.6
user1@vm1:~$ cd /tmp
user1@vm1:/tmp$ tar -zxvf ~/root.tgz
opt/root/
opt/root/bin/
opt/root/bin/bash
opt/root/lib64/
opt/root/lib64/ld-linux-x86-64.so.2
opt/root/lib/
opt/root/lib/libdl.so.2
opt/root/lib/libncurses.so.5
opt/root/lib/libc.so.6
user1@vm1:/tmp$ ls -al
total 19
drwxrwxrwt  6 root  root   1024 Jul  5 04:17 .
drwxr-xr-x 22 root  root   1024 Jul  3 08:29 ..
drwxrwxrwt  2 root  root   1024 Jul  3 08:41 .ICE-unix
drwx------  2 root  root  12288 Jul  3 07:47 lost+found
drwxr-xr-x  3 user1 user1  1024 Jul  5 03:24 opt
-rw-r--r--  1 root  root    489 Jul  3 10:14 sources.list
-r--r-----  1 root  root    491 Jul  3 10:21 sudoers
drwxrwxrwt  2 root  root   1024 Jul  3 08:41 .X11-unix
user1@vm1:/tmp$ dd_if=$(mount | grep /tmp | cut -d ' ' -f 1) && echo $dd_if
/dev/sda8
user1@vm1:~$ cd && ls -alh
total 243M
drwxr-xr-x 3 user1 user1 4.0K Jul  5 04:27 .
drwxr-xr-x 4 root  root  4.0K Jul  3 08:39 ..
-rw------- 1 user1 user1   22 Jul  3 10:45 .bash_history
-rw-r--r-- 1 user1 user1  220 Jul  3 08:39 .bash_logout
-rw-r--r-- 1 user1 user1 3.2K Jul  3 08:39 .bashrc
-rw------- 1 user1 user1   52 Jul  5 04:12 .lesshst
drwxr-xr-x 3 user1 user1 4.0K Jul  5 03:23 opt
-rw-r--r-- 1 user1 user1  675 Jul  3 08:39 .profile
-rw-r--r-- 1 user1 user1 1.3M Jul  5 04:25 root.tgz
-rw-r--r-- 1 root  root  241M Jul  5 04:36 tmp.img
user1@vm1:~$ sudo losetup /dev/loop1 ~/tmp.img && sudo mount /dev/loop1 /mnt/
user1@vm1:~$ ls -al /mnt
total 19
drwxrwxrwt  6 root  root   1024 Jul  5 04:17 .
drwxr-xr-x 22 root  root   1024 Jul  3 08:29 ..
drwxrwxrwt  2 root  root   1024 Jul  3 08:41 .ICE-unix
drwx------  2 root  root  12288 Jul  3 07:47 lost+found
drwxr-xr-x  3 user1 user1  1024 Jul  5 03:24 opt
-rw-r--r--  1 root  root    489 Jul  3 10:14 sources.list
-r--r-----  1 root  root    491 Jul  3 10:21 sudoers
drwxrwxrwt  2 root  root   1024 Jul  3 08:41 .X11-unix
user1@vm1:~$ sudo umount /mnt && sudo losetup -d /dev/loop1
user1@vm1:~$ sudo umount $dd_if && sudo mkfs.ext3 $dd_if
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
61752 inodes, 246784 blocks
12339 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
31 block groups
8192 blocks per group, 8192 fragments per group
1992 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729, 204801, 221185
 
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
 
This filesystem will be automatically checked every 27 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
user1@vm1:~$ new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid
f8288adc-3ef9-4a6e-aab2-92624276b8ba
user1@vm1:~$ grep '/tmp' /etc/fstab
# /tmp was on /dev/sda8 during installation
UUID=011b4530-e4a9-4d13-926b-48d9e33b64bf /tmp ext3 defaults 0 2
user1@vm1:~$ sed "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    defaults        0       0
# / was on /dev/sda1 during installation
UUID=91aacf33-0b35-474c-9c61-311e04b0bed1 /               ext3    errors=remount-ro 0       1
# /home was on /dev/sda9 during installation
UUID=e27b0efb-8cf0-439c-9ebe-d59c927dd590 /home           ext3    defaults        0       2
# /tmp was on /dev/sda8 during installation
UUID=f8288adc-3ef9-4a6e-aab2-92624276b8ba /tmp ext3 defaults 0 2
# /usr was on /dev/sda5 during installation
UUID=9f49821b-7f94-4915-b9a9-ed9f12bb6847 /usr            ext3    defaults        0       2
# /var was on /dev/sda6 during installation
UUID=b7e908a1-a1cd-4d5c-bc79-c3a99d003e7c /var            ext3    defaults        0       2
# swap was on /dev/sda7 during installation
UUID=292981d7-5a17-488f-8d9a-176b65f45d46 none            swap    sw              0       0
/dev/scd0       /media/cdrom0   udf,iso9660 user,noauto     0       0
sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab
sudo mount -a && ls /tmp
user1@vm1:~$ sudo umount /tmp && pv ~/tmp.img | sudo dd of=$dd_if bs=10M
 241MB 0:00:04 [54.2MB/s] [===============================================================================================================>] 100%
0+1928 records in
0+1928 records out
252706816 bytes (253 MB) copied, 5.52494 s, 45.7 MB/s
user1@vm1:~$ rm -v tmp.img
rm: remove write-protected regular file `tmp.img'? y
removed `tmp.img'
user1@vm1:~$
```

## 解释

1.  在你的主目录中创建归档或`/opt/root/`。归档文件的扩展名是`.tgz`，因为这个归档实际上由两部分组成，就像是俄罗斯套娃。第一部分由字母`t`指定，是一个大文件，其中所有归档文件由程序`tar`合并。第二部分由字母`gz`指定 ，意味着`tar`调用`gzip`程序来压缩它。
1.  测试这个归档。
1.  将目录更改为`/tmp`。
1.  解压你的归档。
1.  打印目录内容。
1.  提取挂载在`/tmp`上的分区的名称，将其存储在`dd_if`变量中，如果提取成功，打印出`dd_if`值。`if`代表输入文件。
1.  将整个分区复制到你的主目录中的`tmp.img`。dd 使用超级用户调用，因为你正在访问代表你的分区的文件`/dev/sda8`，该分区对普通用户不可访问。
1.  将目录更改为你的主目录并打印出其内容。
1.  告诉 Linux 将`tmp.img`文件用作（一种）物理分区并挂载它。
1.  打印出`tmp.img`的内容。你可以看到它真的是`/tmp`的精确副本 。
1.  
1.  解除挂载`tmp.img`，并告诉 Linux 停止将其看做分区。
1.  解除挂载`/tmp`并在那里创建新的文件系统，删除该过程中的所有东西。
1.  提取你的新`/tmp`文件系统的UUID ，将其存储在`new_uuid`中，并打印出来。
1.  从`/etc/fstab`中打印描述旧的`/tmp`分区的一行。
1.  向你展示，修改后的`/etc/fstab`如何工作。通过使用正则表达式来完成，这个表达式用作掩码，定义了这一行：
    
    ```
    UUID=f8288adc-3ef9-4a6e-aab2-92624276b8ba /tmp ext3 defaults 0 2
    ```
    
    完成这本书后，我会给你一个链接，让你学习如何创建这样的正则表达式。
1.  使用新的 UUID 实际替换`/tmp`旧的 UUID。
1.  挂载`/etc/fstab`中描述的所有文件系统，并列出新`/tmp`的内容
1.  解除挂载新的`/tmp`并从`tmp.img`恢复旧`/tmp`。
1.  获取旧`/tmp`的 UUID，它实际上与创建新文件系统之前相同，因为`tmp.img`是旧的`/ tmp`的完美副本。
1.  在`/etc/fstab`中用旧的 UUID 替换新的 UUID 。
1.  从`/etc/fstab`挂载所有文件系统。如果此命令不会导致错误，你可能一切正常。恭喜。
1.  从你的主目录中删除`tmp.img`。

## 附加题

+   尝试详细解释每个命令的作用。拿出一张纸，把它全部写出来。在`man`中查找在所有不能很好理解的命令和参数。
+   这个有些过早了，但为什么你能作为`user1`来发出删除命令，从你的主目录中删除`tmp.img`，考虑到`tmp.img`由 root 创建？
