/dev/stdin 파일에서 tar 생성

/dev/stdin 파일에서 tar 생성

STDIN을 통해 임의의 데이터를 전달하고 일반 파일처럼 압축하는 방법을 찾고 있습니다.

나는 이것을 시도했다

$ echo test | tar -cf test.tar /dev/stdin

test.tar그러면 내용이 포함된 파일이 제공됩니다 dev/stdin. 파일 stdin은 링크입니다 /proc/self/fd/0.

내가 원하는 것은 dev/stdinTAR 파일 내부에 text 가 포함된 일반 파일이 있다는 것입니다 test. 다음과 같은 상황에서도 비슷한 상황이 발생합니다.

$ tar -cf test.tar <(echo test)

하지만 이름은 다릅니다.

이것이 가능한가?

답변1

내 생각엔 당신이 여기서 원하는 것을 할 수 없을 것 같아요. 접근 방식의 문제점은 tar파일과 디렉터리 트리를 처리하고 다음과 같은 명령을 제공하지 않는다는 것입니다.

$ echo test | tar -cf test.tar /dev/sdtin

다음과 같은 서브쉘을 사용하여 임시 파일의 문자열을 "래핑"하려고 시도하더라도:

$ tar -cf test.tar <(echo test)

콘텐츠가 여전히 TAR 압축을 위해 다음과 같은 임시 파일 설명자를 사용하고 있음을 확인할 수 있습니다.

$ tar tvf test.tar
lr-x------ vagrant/vagrant   0 2018-08-04 23:52 dev/fd/63 -> pipe:[102734]

문자열을 압축하고 싶다면 파일 컨텍스트에 넣어야 합니다. 따라서 다음과 같이 해야 합니다.

$ echo "test" > somefile && tar -cf /tmp/test.tar somefile

TAR 파일에 해당 파일이 존재하는 것을 확인할 수 있습니다.

$ tar tvf /tmp/test.tar
-rw-rw-r-- vagrant/vagrant   5 2018-08-05 00:00 somefile

tar를 사용하여 데이터 복사

오랫동안 Unix를 사용해 온 대부분의 사람들은 아마도 다음과 같은 패턴을 본 적이 있을 것입니다.

$ (cd /; tar cf - .)|(cd /mnt/newroot; tar pxvf -)

나는 과거에 한 위치에서 다른 위치로 데이터를 복사하는 데 이것을 사용했습니다. SSH를 통해서도 사용할 수 있습니다. 다른 방법은 U&L Q&A에서 다음과 같이 논의됩니다.busybox를 사용하여 루트 디렉터리 트리 복제.

백업/

전체 하드 드라이브를 백업하려는 경우에도 이 방법을 사용할 수 있습니다.

$ sudo tar -cvpzf backup.tar.gz --exclude=/backup.tar.gz --one-file-system /

인용하다

답변2

전송하려는 최종 크기(바이트)를 알고 있는 경우 tar 파일을 스트림으로 생성할 수 있습니다. 그런 다음 데이터 스트림 앞에 초기 512바이트 헤더를 생성하고 그 뒤에 후행 패딩을 생성해야 합니다. tar파일 형식이 다양하므로 파일의 정확한 변형 에 따라 다릅니다 . 다음 단계가 도움이 될 수 있습니다.

  1. 데이터 스트림과 동일한 크기의 구멍 파일 생성

    $ dd if=/dev/zero of=mystream bs=1 count=0 seek=$SIZE

    이제 이 mystream파일은 "홀" 파일이며 데이터 스트림과 $SIZE 크기가 동일한 것처럼 보이지만 실제로는 디스크 공간을 차지하지 않습니다.

  2. 지정된 크기의 파일에 대한 tar헤더를 만드는 데 사용됩니다.mystream

    $ tar cf - mystream | head -c 512 > header

    취약점 tar이 없는 파일을 생성하려면 처음 512바이트를 제외하고 모두 삭제하는 것이 중요합니다. 그런 다음 실수로 복사되는 것을 방지하기 위해 구멍 파일을 삭제하십시오.

    $ rm mystream

  3. 512개의 블록을 채우는 패딩 테일을 만듭니다.

    $ head -c $((echo "scale=0; 512 - $SIZE % 512" | bc )) > trailer

  4. 헤더와 트레일러가 포함된 $STREAM(크기 $SIZE)의 타르 스트림을 만듭니다.

    $ cat header $STREAM trailer

    이를 표준 출력이 아닌 다른 곳으로 스트리밍할 수도 있습니다.

답변3

를 사용하면 파이프 대신 임시 파일을 사용하는 프로세스 대체 형식을 zsh사용할 수 있습니다 . GNU 옵션을 =(...)사용하면 아카이브 멤버의 이름을 변경할 수 있습니다:tar--transform

tar --transform='s/.*/test-file/' -zcf file.tar.gz =(echo test)

0600 권한과 content 권한을 가진 멤버를 file.tar.gz생성 합니다 .test-filetest\n

bash(또는 )을 사용하여 zsh다음을 수행할 수 있습니다.

tar --transform='s/.*/test-file/' -zchf file.tar.gz /dev/stdin <<< "$(echo test)"

Here-strings는 이러한 쉘에서도 임시 파일을 사용합니다. 그러나 명령 대체는 제거된다는 점에 유의하십시오.모든후행 개행 및 추가하나뒤로 및 bashNUL 바이트 스트립에 있습니다.

관련 정보