我正在尝试修改包含cpio
.因此,我首先需要提取图像,然后打包图像。由于映像包含整个文件系统,所有文件都以绝对文件名给出,因此我无法直接打包和解包它,因为它会与我的机器的根系统冲突。
因此,在解压时,我通常--no-absolute-filenames
将其解压到我选择的工作目录中。现在我又想打包了。如果我只是打包它,我只会得到这样的文件:
/path/to/working/directory/file1
/path/to/working/directory/file2
/path/to/working/directory/file3
或者
./file1
./file2
./file3
代替
/file1
/file2
/file3
有谁知道我如何才能获得所需的输出?谷歌到目前为止还没有帮助我。
我确实需要输出文件中的绝对路径名,因为我将其用于 u-boot uImage 文件系统映像,并且这要求路径是绝对路径,否则它将无法启动。
答案1
如果你有 python 并且:
- 安装libarchive-c(例如使用
pip install libarchive-c
) - 将所有文件放在
root
当前目录下的目录下(我使用过
mkdir -p root/xyz ; echo 1 > root/abc.txt ; echo 2> root/xyz/def.txt
) 将以下内容另存为
abscpio
并使其可执行 (chmod 755 abscpio
)#! /usr/bin/env python import os import sys from libarchive import ffi from libarchive.write import ( new_archive_write, ArchiveWrite, new_archive_read_disk) from libarchive.entry import new_archive_entry, ArchiveEntry from libarchive.ffi import ( ARCHIVE_EOF, entry_sourcepath, entry_clear, read_next_header2, read_disk_descend, write_header, write_data, write_finish_entry, ) class AbsArchiveWrite(ArchiveWrite): def add_abs_file(self, path, store_path): """Read the given paths from disk and add them to the archive. """ write_p = self._pointer block_size = ffi.write_get_bytes_per_block(write_p) if block_size <= 0: block_size = 10240 # pragma: no cover with new_archive_entry() as entry_p: entry = ArchiveEntry(None, entry_p) with new_archive_read_disk(path) as read_p: while 1: r = read_next_header2(read_p, entry_p) if r == ARCHIVE_EOF: break entry.pathname = store_path read_disk_descend(read_p) write_header(write_p, entry_p) try: with open(entry_sourcepath(entry_p), 'rb') as f: while 1: data = f.read(block_size) if not data: break write_data(write_p, data, len(data)) except IOError as e: if e.errno != 21: raise # pragma: no cover write_finish_entry(write_p) entry_clear(entry_p) if os.path.isdir(path): break base_dir = sys.argv[2] with new_archive_write('cpio', None) as archive_p: ffi.write_open_filename_w(archive_p, sys.argv[1]) a = AbsArchiveWrite(archive_p) for root, dir_names, file_names in os.walk(base_dir): for dir_name in dir_names: full_name = os.path.join(root, dir_name) a.add_abs_file(full_name, full_name.replace(base_dir, '/', 1)) for file_name in file_names: full_name = os.path.join(root, file_name) a.add_abs_file(full_name, full_name.replace(base_dir, '/', 1)) print '----- listing ' + sys.argv[1] os.system('cpio -itv -I ' + sys.argv[1])
你可以做:
abscpio my_arch.cpio root/
输出类似于:
----- listing my_arch.cpio
drwxrwxr-x 2 anthon users 0 Jun 25 18:59 /xyz
-rw-rw-r-- 1 anthon users 2 Jun 25 18:59 /abc.txt
-rw-rw-r-- 1 anthon users 0 Jun 25 18:59 /xyz/def.txt
对于生产,您可能需要删除脚本中的最后两行。
链接也被存储,但我没有尝试过其他“文件”类型。
答案2
使用帕克斯以及-s
在将文件添加到存档时重命名文件的选项。 Pax是POSIX 传统实用程序的替代品tar
;cpio
一些 Linux 发行版默认情况下不安装它,但它应该始终作为软件包提供。
pax -w -x cpio -s '~^[/]*~~' root-directory >archive.cpio