使用不同的绝对目录创建cpio文件

使用不同的绝对目录创建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

有谁知道我如何才能获得所需的输出?谷歌到目前为止还没有帮助我。

我确实需要输出文件中的绝对路径名,因为我将其用于 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 传统实用程序的替代品tarcpio一些 Linux 发行版默认情况下不安装它,但它应该始终作为软件包提供。

pax -w -x cpio -s '~^[/]*~~' root-directory >archive.cpio

相关内容