U-Boot

創建具有不同絕對目錄的 cpio 文件

  • June 26, 2015

我正在嘗試修改包含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 對傳統實用程序的替代tarcpio;一些 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

對於生產,您可能希望從腳本中刪除最後兩行。

連結也被儲存,但我沒有嘗試過其他“文件”類型。

引用自:https://unix.stackexchange.com/questions/212157