STDIN을 통해 임의의 데이터를 전달하고 일반 파일처럼 압축하는 방법을 찾고 있습니다.
나는 이것을 시도했다
$ echo test | tar -cf test.tar /dev/stdin
test.tar
그러면 내용이 포함된 파일이 제공됩니다 dev/stdin
. 파일 stdin
은 링크입니다 /proc/self/fd/0
.
내가 원하는 것은 dev/stdin
TAR 파일 내부에 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
파일 형식이 다양하므로 파일의 정확한 변형 에 따라 다릅니다 . 다음 단계가 도움이 될 수 있습니다.
데이터 스트림과 동일한 크기의 구멍 파일 생성
$ dd if=/dev/zero of=mystream bs=1 count=0 seek=$SIZE
이제 이
mystream
파일은 "홀" 파일이며 데이터 스트림과 $SIZE 크기가 동일한 것처럼 보이지만 실제로는 디스크 공간을 차지하지 않습니다.지정된 크기의 파일에 대한
tar
헤더를 만드는 데 사용됩니다.mystream
$ tar cf - mystream | head -c 512 > header
취약점
tar
이 없는 파일을 생성하려면 처음 512바이트를 제외하고 모두 삭제하는 것이 중요합니다. 그런 다음 실수로 복사되는 것을 방지하기 위해 구멍 파일을 삭제하십시오.$ rm mystream
512개의 블록을 채우는 패딩 테일을 만듭니다.
$ head -c $((echo "scale=0; 512 - $SIZE % 512" | bc )) > trailer
헤더와 트레일러가 포함된 $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-file
test\n
bash
(또는 )을 사용하여 zsh
다음을 수행할 수 있습니다.
tar --transform='s/.*/test-file/' -zchf file.tar.gz /dev/stdin <<< "$(echo test)"
Here-strings는 이러한 쉘에서도 임시 파일을 사용합니다. 그러나 명령 대체는 제거된다는 점에 유의하십시오.모든후행 개행 및 추가하나뒤로 및 bash
NUL 바이트 스트립에 있습니다.