그게 그렇게 어려울 줄은 몰랐어요. 저는 그냥 타르를 사용합니다. 두 가지 데이터가 있습니다. 하나는 대규모 pcap 데이터 페이로드이고 다른 하나는 Python 절임 파일 형태의 추가 메타데이터입니다. 내 목표는 이 두 파일을 포함하는 .tar 파일을 만들고 XZ를 사용하여 압축하는 것입니다.
.tar.xz 파일에서 메타데이터 파일을 빠르게 추출할 수 있도록 tarball을 색인화할 수 있기를 원합니다. 저는 tar 파일을 자동으로 색인화하는 xz 압축을 위해 PIXZ를 사용합니다. 압축하는 pcap 데이터가 너무 크기 때문에 압축하기 전에 디스크를 건드리고 싶지 않습니다. 나는 tcprewrite를 사용하여 다른 변경 사항을 적용하고 있지만 이는 중요하지 않습니다.
명명된 파이프를 사용하도록 모든 도구를 설정했는데 아름답게 작동하고 매우 빠릅니다. 불행한 문제는 tar를 명명된 파이프와 함께 사용할 수 없다는 것입니다. 명명된 파이프를 압축하려고 할 때마다 /dev/fd/#numbers가 tarball에 기록됩니다. pcap 데이터를 디스크나 /dev/shm에 기록하여 tar할 수는 없습니다. 중요한 점은 pcap 데이터가 압축되기 전에 디스크에 도착하지 않는다는 것입니다.
저는 전체 유틸리티를 Python으로 작성 중이므로 Python의 tarfile 모듈을 사용하려고 합니다. 문서에서는 FIFO와 함께 작동한다고 주장하지만 tarfile.add()를 사용할 때도 동일한 문제가 발생합니다. zip(명명된 파이프를 사용하기 위한 -FI 옵션이 있음)과 같은 대안을 찾아보았지만 기존 인프라에서는 tar를 사용해야 합니다.
나는 gnutar와 bsdtar를 시도했지만 둘 다 파이프와 함께 작동하지 않습니다. 최종 결과가 색인화되어 있고 메타데이터에 빠르게 액세스할 수 있는 .tar.xz 파일이라면 어떤 도구를 사용하게 되든 상관없습니다.
답변1
이것 때문에 좌절하지 마십시오... 당신이 그것을 알아낼 것이라고 확신합니다!
내 생각에 tar가 당신을 혼란스럽게 하는 것은 "명명된 파이프를 지원한다"는 것은 명명된 파이프를 인식하고 저장할 수 있다는 것을 의미한다는 것입니다.명명된 파이프로나중에 다시 명명된 파이프로 복원할 수 있도록 아카이브에 저장합니다. 이는 실제로 원하는 것이 아닙니다.
또한 파일을 설명하는 항목이 내용보다 먼저 저장되고 파일 항목에는 파일 크기가 포함되어야 하므로 내용의 정확한 크기를 알지 못하는 한 tar 파일의 형식은 수행 중인 작업에 그다지 적합하지 않습니다. 미리 하는게 힘들죠...
가지다이 솔루션(TarFileStdin 참조), 이 문제를 해결하기 위해 해킹을 사용합니다. 파일 크기가 0인 TarInfo를 삽입한 다음 파일의 내용을 저장하고 마지막으로 원본 TarInfo의 오프셋을 찾아 올바른 크기로 덮어씁니다... 조금 너무 해킹적이지만 작동해야 합니다. .... .하지만 계속 읽어주세요.
".tar.xz 파일에서 메타데이터 파일을 빠르게 추출할 수 있도록 tarball을 색인화할 수 있기를 원합니다"라고 언급하셨기 때문에 ZIP 파일처럼 보입니다! ZIP 형식은 먼저 모든 파일의 내용을 저장한 다음 ZIP 끝에 파일 정보와 오프셋 테이블을 저장합니다. 그런 의미에서 말씀하신 것처럼 색인이 생성됩니다. 이 도구는 파일 끝부터 시작하여 파일 테이블을 쉽게 찾을 수 있기 때문에 ZIP의 내용을 빠르게 나열할 수 있습니다.
ZIP의 기본 압축 형식을 사용하거나 ZIP의 저장 모드(비압축)를 사용하고 거기에 xyz.pcap.xz 파일을 추가할 수 있습니다. *.xz 파일을 ZIP에 추가하면 Parallelxz와 같은 외부 압축기를 쉽게 사용할 수 있습니다.
Python 3 zipfile.ZipFile
객체에는open()
방법이름만으로 파일을 추가하고 내용을 쓸 수 있는 파일 개체를 받을 수 있습니다.
API를 사용하고 shutil.copyfileobj()
명명된 파이프의 압축된 pcap을 ZIP 파일에 추가할 수 있습니다.
import shutil
import zipfile
with zipfile.ZipFile('mydata.zip', 'w') as zf:
with zf.open('xyz.pcap.xz', 'w') as outputf:
with open('/path/to/namedpipe', 'r') as inputf:
shutil.copyfileobj(inputf, outputf)
zf.write('metadata.pickle') # from local directory
이 코드 조각은 xz로 압축된 pcap 데이터를 명명된 파이프에 기록하고 메타데이터가 현재 디렉터리에 "metadata.pickle"이라는 파일로 직렬화되었다고 가정합니다. (물론 open()
ZipFile을 사용하여 피클 메타데이터를 ZIP 파일의 항목으로 직접 직렬화할 수도 있습니다!)
zipfile의 기본 압축을 사용하려면 ZipFile에 대한 기본 압축을 설정할 수 있습니다.
with zipfile.ZipFile('mydata.zip', 'w', zipfile.ZIP_LZMA) as zf:
(기본값은 ZIP_STORED입니다. 이는 압축이 없음을 의미하며, xz 압축 데이터를 그곳으로 전송하는 경우 아마도 원하는 것일 것입니다.)
보다zip 파일에 대한 설명서자세한 내용은. 최신 Python에는 더 많은 기능이 있습니다. 예를 들어 Python 3.5에서는 실제로 zip 파일을 파이프에 작성하여 SSH를 통해 원격 호스트에 직접 업로드할 수 있습니다.
이것이 당신에게 도움이 되기를 바랍니다! 정말로 타르볼이 필요하다면 시도해 보십시오.이 답변, 하지만 Python 3의 zipfile 솔루션을 사용하는 것이 설명하는 사용 사례에 더 나은 접근 방식이라고 생각합니다! 따라서 이 형식이 작동한다면 정말 추천하고 싶습니다.