다른 절대 디렉토리를 사용하여 cpio 파일 만들기

다른 절대 디렉토리를 사용하여 cpio 파일 만들기

include를 수정하려고 합니다 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 파일 시스템 이미지에 사용하고 있기 때문에 출력 파일에 절대 경로 이름이 필요합니다. 그렇지 않으면 부팅되지 않습니다.

답변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

관련 정보