U-Boot
創建具有不同絕對目錄的 cpio 文件
我正在嘗試修改包含
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
有誰知道我怎樣才能得到想要的輸出?到目前為止,Google並沒有幫助我。
我真的需要輸出文件中的絕對路徑名,因為我將它用於 u-boot uImage 文件系統映像,這要求路徑是絕對的,否則將無法啟動。
使用pax及其
-s
選項在文件添加到存檔時重命名文件。Pax 是 POSIX 對傳統實用程序的替代tar
品cpio
;一些 Linux 發行版預設不安裝它,但它應該始終以包的形式提供。pax -w -x cpio -s '~^[/]*~~' root-directory >archive.cpio
如果你有 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
對於生產,您可能希望從腳本中刪除最後兩行。
連結也被儲存,但我沒有嘗試過其他“文件”類型。