Linux dd和cpio命令

来源:互联网 发布:json打印出来 编辑:程序博客网 时间:2024/04/29 18:12

最近经常遇到ddcpio两个命令,觉得很有必要写篇文章强化下记忆。

dd命令

用途和命名

dd命令的用途是拷贝和转换文件。这个可以通过man dd知道:

dd - convert and copy a file

通过info dd命令可以得到一段不同的说明:

`dd' copies a file (from standard input to standard output, by default)
with a changeable I/O block size, while optionally performing
conversions on it.

总的来说,dd命令就是按照每次一块的方式来拷贝文件,同时在拷贝的过程中还能对内容进行转换。

至于dd命令为啥叫这个名字,通过查询wifi页面可知,dd可能是data description的缩写:

The name dd may be an allusion to the DD statement found in IBM's Job Control Language (JCL),[3] where the initials stand for "Data Description.

拷贝数据

dd经常被用来拷贝数据,从一个地方拷贝到另一个地方。为啥不用copy就好?因为I/O操作(尤其是磁盘I/O)都是基于块的,因此dd提供的基于块的数据拷贝操作有性能上的优势。我们通过下面的例子来看

~/programming/test$ dd bs=K if=/dev/zero of=/dev/null16759236+0 records in16759236+0 records out17161457664 bytes (17 GB) copied, 22.5896 s, 760 MB/s~/programming/test$ dd bs=b if=/dev/zero of=/dev/null17889445+0 records in17889445+0 records out9159395840 bytes (9.2 GB) copied, 23.565 s, 389 MB/s

在上面的例子中,我们将数据从/dev/zero拷贝到/dev/null,两次拷贝指定不同的块大小,第一次bs=b(b是512字节),第二次指定bs=K(K是1024字节),可见块大的拷贝性能高。但是,实际情况肯定不是块越到拷贝性能越好,针对不同的设备应该会有不同的最优值,我不是这方面的专家,这里就不展开了。

常用选项

if=FILE: 输入文件,默认是stdin
of=FILE: 输出文件,默认是stdout
bs=BYTES: 指定块大小,默认是b,也就是512字节。
count=N: 拷贝块的数量,count * bs就是拷贝的总字节数

上面的选项是最常用的,因为拷贝的过程一半就是需要三个参数:源、目的和大小。下面是几个示例,从wifi搬过来的:

# 写1G的空数据到一个文件,再读出来,用来测试读写性能$dd if=/dev/zero of=file_1GB bs=K count=MB1000000+0 records in1000000+0 records out1024000000 bytes (1.0 GB) copied, 3.67137 s, 279 MB/s$dd if=file_1GB of=/dev/null bs=K count=MB1000000+0 records in1000000+0 records out1024000000 bytes (1.0 GB) copied, 1.49088 s, 687 MB/s

上面的数据是我的固态硬盘的真实数据。

转换数据

dd命令还有两个参数是convcbs

conv: 转换操作,执行一些指定的转换操作,所有的操作可以看man手册
cbs:每次转换的块大小,有些conv操作必须指定cbs的值(比如block操作),有些则不用(比如ucase)操作。

举个最简单的例子,把一个文件的内容都转换成大写:

$dd if=log conv=ucaseWRITEHELLO, WORLDHELLO, WORLD

常见应用

我经常见到的,也是我本人常用的,是用dd命令来生成一个指定大小的全0文件,然后将其格式化为ext文件系统后挂载,这样就能添加文件到这个文件系统中了。

cpio命令

cpio也是GNU旗下的一个工具,主要用来将文件拷贝到归档文件或者是从归档文件中将文件拷贝出来,这里说的归档文件指的是cpio格式的文件cpio的man手册内容较少,可以查看在线帮助页面获取更多信息。从官网的手册上可以看到cpio还可以用于软盘和磁带,不过现在一般是用不上了。

cpio有以下三种工作方式:

  • Copy-out mode: 将指定的文件拷贝到归档文件中,也就是生成归档文件
  • Copy-in mode: 将指定的文件从归档文件中拷贝出来,默认是解压所有文件,也可以只解压指定的文件
  • Copy-pass mode: 将文件从一个目录拷贝到另一个目录

Copy-out mode

Copy-out模式从标准输入读取要存档的文件列表,默认格式是每行一个文件,以换行符区分(也可以使用--null选项,改成以空字符区分),将文件打包成一个存档文件输出到标准输出,不过我们一般是用管道来和cpio程序打交道。下面的例子将目录d中的文件打包成d.cpio:

~/temp$ ll dtotal 8-rw-rw-r-- 1 diabloneo diabloneo 7 Aug  7 22:30 a-rw-rw-r-- 1 diabloneo diabloneo 6 Aug  7 22:30 b~/temp$ find d | cpio -o > d.cpio1 block~/temp$ lltotal 8drwxrwxr-x 2 diabloneo diabloneo 4096 Aug  7 22:32 d/-rw-rw-r-- 1 diabloneo diabloneo  512 Aug  7 22:34 d.cpio

注意,生成的d.cpio文件的大小,是512,但是打包进去的目录和文件没有这么大。原因是cpio程序也是根据块来进行I/O操作的,默认的块大小是512,要更改这个块大小,可以使用-C参数。

Copy-in mode

Copy-in模式从标准输入读入一个归档文件,然后拷贝出所有的或者指定的文件,也可以只列出归档文件中的文件列表。

列出归档文件中的内容:

~/temp$ cpio -t < d.cpiodd/ad/b1 block

解压归档文件到目录c

~/temp$ mkdir c~/temp$ cd c~/temp/c$ cpio -i < ../d.cpio1 block~/temp/c$ lltotal 4drwxrwxr-x 2 diabloneo diabloneo 4096 Aug  7 22:46 d/~/temp/c$ ll dtotal 8-rw-rw-r-- 1 diabloneo diabloneo 7 Aug  7 22:46 a-rw-rw-r-- 1 diabloneo diabloneo 6 Aug  7 22:46 b

Copy-pass mode

Copy-pass模式就把文件从一个目录拷贝到令一个目录:

~/temp$ mkdir e~/temp$ find d | cpio -p e1 block~/temp$ ll etotal 4drwxrwxr-x 2 diabloneo diabloneo 4096 Aug  7 22:51 d/~/temp$ ll e/dtotal 8-rw-rw-r-- 1 diabloneo diabloneo 7 Aug  7 22:51 a-rw-rw-r-- 1 diabloneo diabloneo 6 Aug  7 22:51 b

归档文件格式

cpio有一个--format选项用于指定创建归档文件时所用的格式,即copy-out模式使用的格式。Copy-in模式自动识别格式,无需指定。官方手册里列出了好几种格式,这里不一一列出,不过要说明一下cpio创建的归档文件对归档文件大小以及inode数量都有限制。默认使用的格式是bin格式,支持2G大小的归档文件,inode数量不能超过6K个。对于归档整个文件系统,可以使用newc格式,支持4G大小的归档文件,以及大于6K的inode数量。当然,不同格式的大小也有所不同,下面是bin格式、newc格式和ustar格式的归档大小比较(都是对前面的d目录进行归档):

~/temp$ lltotal 16drwxrwxr-x 2 diabloneo diabloneo 4096 Aug  7 22:32 d/-rw-rw-r-- 1 diabloneo diabloneo  512 Aug  7 22:37 d.cpio-rw-rw-r-- 1 diabloneo diabloneo  512 Aug  7 23:00 d-newc.cpio-rw-rw-r-- 1 diabloneo diabloneo 3584 Aug  7 23:00 d.tar

常见应用

cpio一般用来存档整个文件系统,在为各种基于Linux的嵌入式系统创建初始的rootfs的时候经常会用到。

0 0