马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
cpio 是一个很老但很扎实的归档工具,常见于内核模块初始-initramfs、rpm/deb 包内部、以及老磁盘对拷场景。它和 tar 最大的区别是:tar 负责归档,gzip 负责压缩,两者各管一段;cpio 可以自己带上压缩参数,但更多时候是「配 gzip/pipe 用」。本文接着上篇,把 cpio 最常用的几个模式与参数(-o 生成、-i 解包、-t 列表、-p 直拷、-u 强制、-f 反向匹配)串成一条完整操作链。
一、先把三种模式记牢
cpio 的模式是单个字母,写在参数最前面:
-o create:从输入(默认标准输入)读文件列表,写归档到标准输出;
-i extract:从归档(默认标准输入)读归档,还原成文件;
-p pass:把一批文件从一处原样搬到另一处,不产生归档文件。
配合的常用开关:-v 显示过程、-d 自动建目录、-m 保留文件权限与时间戳、-u 无条件覆盖、-H 指定归档格式、-f 取反匹配。
二、生成归档:从标准输入拿文件列表
cpio 不会自己遍历目录,它只认标准输入里的一行行文件名。所以标准写法是先用 find 或 ls 产出列表,再管道给 cpio:
ls | cpio -o > p.cpio
这里有个经典坑:ls 当前目录时不带 ./ 前缀,解包时可能按裸文件名恢复,覆盖到当前目录而不是原路径。更稳的写法:
find . -type f | cpio -o > p.cpio
find . -type f -name "*.conf" | cpio -o > conf.cpio
加 -v 看每个文件怎么被写进去,便于确认列表对不对:
find . -type f | cpio -ov > p.cpio
想直接打成 tar 格式(很多老工具只认 tar 头),用 -H tar:
find . -type f | cpio -o -H tar > p.tar
要压缩就接 gzip:
find . -type f | cpio -o | gzip -9 > p.cpio.gz
三、查看归档内容:cpio -t
没解包之前想看看里面有什么,用列表模式:
cpio -t < p.cpio | more
cpio -tv < p.cpio # 带权限、大小、时间
注意 -t 是读标准输入,所以重定向符 < 不能省;写成 cpio -t p.cpio 是错误的,cpio 不把文件名当参数。
四、追加归档:往已有归档里加东西
-o 模式下用 -A 追加。先备份、再加、最后看大小,避免把原归档写坏:
cp p.cpio p.cpio.bak
find ./newdir -type f | cpio -oA -F p.cpio
ls -lh p.cpio
cpio -t < p.cpio | wc -l
如果归档是 gzip 过的,追加会直接失效(流压缩不支持中间插入),这种情况只能重新打包。
五、解包还原:-i 与 -u
最基础的还原:从归档读,按归档里记录的路径写文件,-d 自动补建缺失的目录:
cpio -idv < p.cpio
归档里如果是绝对路径(比如 /etc/nginx/nginx.conf),默认行为是剥掉最前面的斜杠,把文件写到当前目录下的 etc/nginx/ 里,这是 cpio 的默认保护,避免真的覆盖系统文件。想让它按原路径写,必须显式加 -u:
cpio -iduv < p.cpio
-u 的含义是「无条件的」,即覆盖已存在的文件,不做任何提示也不会跳过。生产环境用它之前一定先 cpio -t 看一眼清单,确认路径再动手。这个行为跟 tar 不一样,tar 解绝对路径时通常会给一句「Removing leading `/`」,而 cpio 是静默截断,这也是老手解包前先 -t 的原因。
六、-f:反向匹配,排除某些文件
-f 对后面跟的 -name 模式取反,用来「除了 XXX 都打包」,非常实用:
find . -type f | cpio -o -H tar > all.tar
find . -type f ! -name "*.tmp" | cpio -o -H tar > no_tmp.tar
find . -type f | cpio -o -H tar 2>/dev/null | cpio -idm <-
更常见的组合是排除日志 和临时文件:
find . -type f ! -name "*.log" ! -name "*.swp" | cpio -ov > src.cpio
七、-p:不产生归档的直拷
只是想把一批文件连权限带时间戳搬到别处,又不想落一个归档文件,用 pass 模式。目标目录在最后以参数给出:
find . -type f | cpio -pdm /tmp/target/
cpio -pmv /source/list.txt /tmp/target
-p 与 -o 的区别在于:它不写归档,直接从标准输入读到的路径名,逐个在目标位置重建,并且默认就保留权限与 mtime(即自带 -m)。运维做应急迁移、或者从一台机器拷配置到另一台,用这条最省事。
八、换成 tar 再对比一次
同一个任务用 tar 写会更短,这也是现在很多场景首选 tar 的原因:
tar cf p.tar .
tar czf p.tar.gz .
tar tf p.tar.gz
tar xzf p.tar.gz -C /tmp/target
但 cpio 在这几类场景仍然不可替代:
- initramfs / initrd:Linux 早期启动镜像就是 cpio 归档,
dracut 生成的 initramfs 需要用 unmkinitramfs、lsinitramfs 这两个基于 cpio 的工具查看;
- rpm/deb 内部:很多包里的内容就是 cpio 流,
rpm2cpio xxx.rpm | cpio -idmv 是直接拆包的标准姿势;
- 需要精确控制文件列表:cpio 从标准输入读列表,配合 find 的条件过滤比 tar 的 exclude 更直观。
九、小结
把这条操作链记住就够了:find 出列表 → cpio -o 生成(-H tar 换格式、管道 gzip 压缩)→ cpio -t 看清单 → cpio -idv 解包(绝对路径要 -u)→ 只搬不打包用 cpio -pdm。最容易翻车的两个点是「忘了 < 重定向导致 -t 卡在读终端」和「裸文件名解包覆盖到当前目录」,前者加 <,后者 find . 带上 ./ 前缀或者干脆先 -t 核对。
qidao123.com企服评测-应用市场 编辑提示 |