cpio命令

-- TOC --

cpio是一个非常古老的归档工具。已逐渐被tar替代,但是有些功能是tar不具有的。制作Linux的ramdisk或initramfs会用到此工具。

cpio - copy files to and from archives

cpio用于创建、释放归档文件,也可以对归档文件执行拷入拷出的动作,即向归档文件中追加文件,或从归档文件中提取文件。它也支持tar格式的归档文件,但是对压缩后的tar(如.tar.gz格式)就没法支持了。

cpio的三种运行模式

Copy-out模式:此模式下,cpio将向归档文件中拷入文件,即进行归档操作,所以成为归档模式。它会从标准输入中读取待归档的文件,将它们归档到目标文件中,若未指定归档目标文件,将归档到标准输出中。在copy-out模式下,最典型的应用是使用find来指定待归档文件。(find命令

-o:(--create)指定运行为copy-out模式,即归档模式

Copy-in模式:此模式下,cpio将从归档文件中提取文件,或者列出归档文件中的文件列表。它将从标准输入中读取归档文件。任意cpio的非选项参数都将认为是shell的glob pattern,只有文件名匹配了指定模式时才会从归档文件中提取出来或list出来。在cpio中,通配符不能匹配到"."或"/",所以如有需要,必须显式指定"."或"/"。如果没有指定匹配模式,则解压或列出所有文件。

-i:(--extract)指定运行为copy-in模式,即提取模式

-t:(--list)列出归档文件中的文件列表

Copy-pass模式:

In copy-pass mode, cpio copies files from one directory tree to another, combining the copy-out and copy-in steps without actually using an archive. It reads the list of files to copy from the standard input; the directory into which it will copy them is given as a non-option argument.

一般copy-pass模式与find命令配合,将find的结果copy到另一个目录下。

$ cd <path>
$ find . | cpio -pdm <destination_dir>

-p:(--pass-through)指定copy-pass模式,即目录拷贝模式

cpio示例

将test目录归档,然后显示归档内容

$ find test | cpio -ov > test.a
test
test/b.txt
test/a
test/a/kk
1 block

-v,verbose,显示详细信息

$ ll test.a
-rw-rw-r-- 1 xinlin xinlin 512 10月 25 15:01 test.a
$ cpio -tv < test.a
drwxrwxr-x   3 xinlin   xinlin          0 Oct 25 13:01 test
-rw-rw-r--   1 xinlin   xinlin          5 Oct 25 12:32 test/b.txt
drwxrwxr-x   2 xinlin   xinlin          0 Oct 25 12:37 test/a
-rw-rw-r--   1 xinlin   xinlin          6 Oct 25 12:37 test/a/kk
1 block

如果不想用重定向,可以使用 -F 参数来指定写入或读出的文件名。

$ find test | cpio -o -F test.a
1 block
$ cpio -t -F test.a
test
test/b.txt
test/a
test/a/kk
1 block

避免将归档文件归档

下面这个用法,就会将归档文件一并进行归档:

$ find . | cpio -o --quiet > test.a
$ cpio -t < test.a
.
b.txt
a
a/kk
test.a
1 block

test.a 文件也包含在test.a归档中!

--quiet:Do not print the number of blocks copied at the end of the run.

不是应该find处理完之后才处理cpio吗?非也,管道的作用只是在进程间进行数据传递,但不是一定要等管道左边的处理完成之后才传递,而是一边处理一边传递,如果左边命令处理的太快,导致管道拥堵,那么管道左边的程序将等待管道有空闲时再继续。

解决将自己也归档,使用 -F 参数,给归档文件指定一个别的路径,让find命令搜索不到即可。

--> 为什么这样更好?

网上文章说,在使用find命令与cpio配合的时候,这样更好:

$ find test -depth -print0 | cpio -0 -o -F path/to/test.cpio

find的-depth表示先搜索文件再搜索目录,-print0表示用 null character来代替newline;对应的cpio命令,也是使用-0来表示null character作为分隔符。

因为当文件名中有空格的时候,find不使用-prinit0,cpio不使用-0,这行命令就有错误,空格会成为cpio的一个分隔符。而文件名中肯定不会含有\x00这样的符号,因此更安全!

--> 向归档文件中追加

追加文件:

$ find test | cpio -o --quiet -F test.cpio
$ ls .bashrc | cpio -oA -F test.cpio
8 blocks
$ cpio -t -F test.cpio
test
test/b.txt
test/a
test/a/kk
.bashrc
8 blocks

-A参数用来表示追加!

追加整个目录:

$ find .local | cpio -oA -F test.cpio
838 blocks
$ cpio -t -F test.cpio
test
test/b.txt
test/a
test/a/kk
.bashrc
.local
.local/share
.local/share/tracker
.local/share/tracker/data
.local/share/tracker/data/tracker-store.ontology.journal
.local/share/tracker/data/tracker-store.journal
.local/share/xorg
.local/share/xorg/Xorg.0.log
.local/share/xorg/Xorg.0.log.old
.local/share/ibus-table
.local/share/sounds
.local/share/applications
.local/share/flatpak
.local/share/flatpak/db
.local/share/icc
.local/share/gvfs-metadata
.local/share/gvfs-metadata/root-1bdea7c3.log
.local/share/gvfs-metadata/trash:
.local/share/gvfs-metadata/trash:-df3c53c5.log
.local/share/gvfs-metadata/home-f31e28ce.log
.local/share/gvfs-metadata/home
.local/share/gvfs-metadata/root
.local/share/session_migration-ubuntu
.local/share/keyrings
.local/share/keyrings/user.keystore
.local/share/keyrings/login.keyring
.local/share/evolution
.local/share/evolution/tasks
.local/share/evolution/tasks/trash
.local/share/evolution/tasks/system
.local/share/evolution/tasks/system/tasks.ics
.local/share/evolution/calendar
.local/share/evolution/calendar/trash
.local/share/evolution/calendar/system
.local/share/evolution/calendar/system/calendar.ics
.local/share/evolution/memos
.local/share/evolution/memos/trash
.local/share/evolution/mail
.local/share/evolution/mail/trash
.local/share/evolution/addressbook
.local/share/evolution/addressbook/trash
.local/share/evolution/addressbook/system
.local/share/evolution/addressbook/system/contacts.db
.local/share/evolution/addressbook/system/photos
.local/share/gnome-settings-daemon
.local/share/gnome-settings-daemon/input-sources-converted
.local/share/gnome-shell
.local/share/gnome-shell/application_state
.local/share/gnome-shell/gnome-overrides-migrated
845 blocks

--> 提取归档文件

$ pwd
/home/xinlin/cpio_test
$ cpio -idvu < test.cpio
test
test/b.txt
test/a
test/a/kk
.bashrc
.local
.local/share
.local/share/tracker
.local/share/tracker/data
.local/share/tracker/data/tracker-store.ontology.journal
.local/share/tracker/data/tracker-store.journal
.local/share/xorg
.local/share/xorg/Xorg.0.log
.local/share/xorg/Xorg.0.log.old
.local/share/ibus-table
.local/share/sounds
.local/share/applications
.local/share/flatpak
.local/share/flatpak/db
.local/share/icc
.local/share/gvfs-metadata
.local/share/gvfs-metadata/root-1bdea7c3.log
.local/share/gvfs-metadata/trash:
.local/share/gvfs-metadata/trash:-df3c53c5.log
.local/share/gvfs-metadata/home-f31e28ce.log
.local/share/gvfs-metadata/home
.local/share/gvfs-metadata/root
.local/share/session_migration-ubuntu
.local/share/keyrings
.local/share/keyrings/user.keystore
.local/share/keyrings/login.keyring
.local/share/evolution
.local/share/evolution/tasks
.local/share/evolution/tasks/trash
.local/share/evolution/tasks/system
.local/share/evolution/tasks/system/tasks.ics
.local/share/evolution/calendar
.local/share/evolution/calendar/trash
.local/share/evolution/calendar/system
.local/share/evolution/calendar/system/calendar.ics
.local/share/evolution/memos
.local/share/evolution/memos/trash
.local/share/evolution/mail
.local/share/evolution/mail/trash
.local/share/evolution/addressbook
.local/share/evolution/addressbook/trash
.local/share/evolution/addressbook/system
.local/share/evolution/addressbook/system/contacts.db
.local/share/evolution/addressbook/system/photos
.local/share/gnome-settings-daemon
.local/share/gnome-settings-daemon/input-sources-converted
.local/share/gnome-shell
.local/share/gnome-shell/application_state
.local/share/gnome-shell/gnome-overrides-migrated
845 blocks
$ ll
total 444
drwxrwxr-x  4 xinlin xinlin   4096 10月 25 15:47 ./
drwxr-xr-x 17 xinlin xinlin   4096 10月 25 15:43 ../
-rw-r--r--  1 xinlin xinlin   3771 10月 25 15:47 .bashrc
drwxr-xr-x  3 xinlin xinlin   4096 10月 25 15:44 .local/
drwxrwxr-x  3 xinlin xinlin   4096 10月 25 15:47 test/
-rw-rw-r--  1 xinlin xinlin 432640 10月 25 15:39 test.cpio

-d,如果前导目录不存在,就自动创建。

-u,如果遇到同名文件或目录,强制覆盖!默认情况如果没有-u,在提取cpio归档文件时,遇到同名文件不会覆盖。

--> 第1次搞initrd.img文件

mkdir test
cd test
gzip -dc ../initrd.img | cpio -idm
find -type f | xargs chmod 775
find | cpio -oH newc | gzip -9 > ../initrd_new.img
cd ..
mv initrd_new.img initrd.img

-m,Retain previous file modification times when creating files.

-H,用来指定archiv的format为newc!

本文链接:https://cs.pynote.net/sf/linux/shell/202110252/

-- EOF --

-- MORE --