tar -cvf
937MB 크기의 디렉토리에서 실행 하여 깊이 중첩 된 폴더 구조의 쉽게 다운로드 할 수있는 사본을 만들면 다음과 같은 df -h
출력으로 디스크를 채울 위험이 있습니다 .
/dev/xvda1 7.9G 3.6G 4.3G 46% /
tmpfs 298M 0 298M 0% /dev/shm
관련 질문 :
- 디스크가 가득 찬 경우 왜 Linux (Amazon AMI) 및 / 또는
tar
후드에서 수행되고 있습니까? - 다시 묻지 않고이 정보를 정확하게 어떻게 확인할 수 있습니까?
답변
tar -c data_dir | wc -c
압축하지 않고
또는
tar -cz data_dir | wc -c
gzip 압축
또는
tar -cj data_dir | wc -c
bzip2 압축
디스크에 쓰지 않고 바이트 단위로 생성 된 아카이브의 크기를 인쇄합니다. 그런 다음 대상 장치의 여유 공간과 비교할 수 있습니다.
다음 명령을 사용하여 데이터 디렉토리 크기에 대해 잘못된 가정이있는 경우 데이터 디렉토리 자체의 크기를 확인할 수 있습니다.
du -h --max-depth=1 data_dir
이미 대답했듯이 tar는 아카이브의 각 레코드에 헤더를 추가하고 각 레코드의 크기를 512 바이트의 배수로 반올림합니다 (기본값). 아카이브의 끝은 2 개 이상의 연속 0 채워진 레코드로 표시됩니다. 따라서 압축되지 않은 tar 파일이 파일 자체보다 크고, 파일 수와 512 바이트 경계에 정렬되는 방식에 따라 추가 공간이 결정되는 경우가 항상 있습니다.
물론 파일 시스템 자체는 개별 파일의 내용보다 큰 블록 크기를 사용하므로 압축을 푼 위치에주의하십시오. 파일 시스템은 tar 크기보다 큰 여유 공간이 있어도 작은 파일을 많이 보유하지 못할 수 있습니다!
https://ko.wikipedia.org/wiki/Tar_(computing)#Format_details
답변
tar 파일의 크기는 937MB에 각 파일 또는 디렉토리에 필요한 메타 데이터 크기 (개체 당 512 바이트)와 파일을 512 바이트 경계에 맞추기 위해 추가됩니다.
매우 대략적인 계산에 따르면 데이터의 다른 사본이 3.4GB의 여유 공간을 제공합니다. 3.4GB에는 패딩이 없다고 가정 할 때 약 7 백만 개의 메타 데이터 레코드를위한 공간이 있거나 파일 당 평균 256 바이트의 패딩을 가정하면 더 적습니다. 따라서 tar에 수백만 개의 파일과 디렉토리가 있으면 문제가 발생할 수 있습니다.
당신은 문제를 완화시킬 수 있습니다
z
또는j
옵션을 사용하여 즉시 압축tar
tar
공간이/
부족한 경우 파티션 의 예약 된 공간 이 건드리지 않도록 일반 사용자로 수행하십시오 .
답변
tar
자체적으로 다음 --test
옵션 을 사용하여 아카이브 크기를보고 할 수 있습니다 .
tar -cf - ./* | tar --totals -tvf -
위의 명령은 디스크에 아무것도 쓰지 않으며 tarball에 포함 된 각 파일의 개별 파일 크기를 나열하는 이점이 있습니다. 다양한 z/j/xz
피연산자를 양쪽에 추가하면 |pipe
압축을 처리 할 수 있습니다.
산출:
...
-rwxr-xr-x mikeserv/mikeserv 8 2014-03-13 20:58 ./somefile.sh
-rwxr-xr-x mikeserv/mikeserv 62 2014-03-13 20:53 ./somefile.txt
-rw-r--r-- mikeserv/mikeserv 574 2014-02-19 16:57 ./squash.sh
-rwxr-xr-x mikeserv/mikeserv 35 2014-01-28 17:25 ./ssh.shortcut
-rw-r--r-- mikeserv/mikeserv 51 2014-01-04 08:43 ./tab1.link
-rw-r--r-- mikeserv/mikeserv 0 2014-03-16 05:40 ./tee
-rw-r--r-- mikeserv/mikeserv 0 2014-04-08 10:00 ./typescript
-rw-r--r-- mikeserv/mikeserv 159 2014-02-26 18:32 ./vlc_out.sh
Total bytes read: 4300943360 (4.1GiB, 475MiB/s)
목적을 완전히 확신하지는 않지만 tarball을 다운로드하는 것이 더 중요 할 수 있습니다.
ssh you@host 'tar -cf - ./* | cat' | cat >./path/to/saved/local/tarball.tar
또는 단순히 다음으로 복사하십시오 tar
.
ssh you@host 'tar -cf - ./* | cat' | tar -C/path/to/download/tree/destination -vxf -
답변
나는 이것에 대해 많은 연구를 해왔다. 단어 개수를 사용하여 파일에서 테스트를 수행 할 수 있지만 a와 같은 숫자를 제공하지는 않습니다 du -sb adir
.
tar -tvOf afile.tar | wc -c
du
모든 디렉토리를 4096 바이트로 tar
계산하고 디렉토리를 0 바이트로 계산합니다. 각 디렉토리에 4096을 추가해야합니다.
$(( $(tar -tvOf afile.tar 2>&1 | grep '^d' | wc -l) * 4096)))
그런 다음 모든 문자를 추가해야합니다. 다음과 같은 것 :
$(( $(tar -tvOf afile.tar 2>&1 | grep '^d' | wc -l) * 4096 + $(tar -xOf afile.tar | wc -c) ))
터치 된 파일 (0 바이트 파일) 또는 1 문자 파일을 시도하지 않았기 때문에 이것이 완벽한 지 확실하지 않습니다. 좀 더 가까이 와야합니다.
답변
-cvf
압축을 포함하지 않으므로 ~ 1GB 폴더에서 압축하면 ~ 1GB tar 파일이 생성됩니다 (Flub의 답변에는 tar 파일의 추가 크기에 대한 자세한 내용이 있지만 10,000 개의 파일이 있어도이 파일은 5MB). 4GB 이상의 여유 공간이 있으므로 파티션을 채우지 않습니다.
쉽게 다운로드 할 수있는 사본
대부분의 사람들은 다운로드 측면에서 “보다 작은”과 “더 작은”의 동의어를 고려하므로 여기에서 약간의 압축을 사용해야합니다. bzip2
타르가있는 모든 시스템에서 현재 하루를 사용할 수 있어야한다고 생각 j
합니다. 스위치에 포함 시키는 것이 최선의 선택 일 것입니다. z
(gzip
)가 더 일반적 일 수 있으며 스쿼시가 더 많은 다른 (유비쿼터스) 가능성이 있습니다.
당신이 의미 tar
하는 경우, 작업을 수행 할 때 일시적으로 추가 디스크 공간을 사용합니까, 나는 몇 가지 이유가 아니라고 확신합니다. 하나는 테이프 드라이브가 기본 스토리지의 한 유형으로 거슬러 올라 갔으며 두 가지는 수십 년 동안 진화했습니다 (그리고 압축이 관련되어 있어도 임시 중간 공간을 사용할 필요는 없습니다).
답변
속도가 중요하고 압축이 필요하지 않은 경우을 사용 tar
하여 사용 된 syscall 랩퍼를 후크하여 계산 LD_PRELOAD
하도록 변경할 tar
수 있습니다. 잠재적 인 출력 타르 데이터의 크기를 계산하는 우리의 요구에 맞게 이러한 기능 중 일부를 다시 구현함으로써 많은 작업을 제거 할 수 read
있으며 write
이는 정상 작동시 수행됩니다 tar
. 이것은 tar
컨텍스트에서 커널로 앞뒤로 전환 할 필요가 없기 때문에 훨씬 빠릅니다.stat
요청 된 입력 파일 / 폴더 만 실제 파일 데이터 대신 디스크에서 읽어야하기 .
아래의 코드는 구현 포함 close
, read
및 write
POSIX 기능. 매크로 OUT_FD
는 tar
출력 파일로 사용할 파일 설명자를 제어 합니다. 현재는 표준 출력으로 설정되어 있습니다.
read
count
실제 데이터를 읽지 않은 경우 buf에 데이터를 채우지 않고 바이트 의 성공 값을 반환하도록 변경되었습니다. buf는 압축으로 전달하기위한 유효한 데이터를 포함하지 않으므로 압축을 사용하면 잘못된 값을 계산합니다 크기.
write
입력 count
바이트를 전역 변수 에 합산하고 파일 디스크립터가 일치하는 경우 에만 바이트 total
의 성공 값을 리턴하도록 변경되었습니다 . 그렇지 않으면 동일한 이름의 syscall을 수행하기 위해 획득 한 원래 랩퍼를 호출합니다 .count
OUT_FD
dlsym
close
여전히 원래 기능을 모두 수행하지만 파일 디스크립터가 OUT_FD와 일치 tar
하면 tar 파일을 작성하려고 시도한 것으로 알고 있으므로 total
숫자가 최종이고 stdout에 인쇄합니다.
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>
#include <dlfcn.h>
#include <string.h>
#define OUT_FD 1
uint64_t total = 0;
ssize_t (*original_write)(int, const void *, size_t) = NULL;
int (*original_close)(int) = NULL;
void print_total(void)
{
printf("%" PRIu64 "\n", total);
}
int close(int fd)
{
if(! original_close)
{
original_close = dlsym(RTLD_NEXT, "close");
}
if(fd == OUT_FD)
{
print_total();
}
return original_close(fd);
}
ssize_t read(int fd, void *buf, size_t count)
{
return count;
}
ssize_t write(int fd, const void *buf, size_t count)
{
if(!original_write)
{
original_write = dlsym(RTLD_NEXT, "write");
}
if(fd == OUT_FD)
{
total += count;
return count;
}
return original_write(fd, buf, count);
}
읽기 디스크 액세스 및 일반 tar 조작의 모든 시스템 호출이 LD_PRELOAD
솔루션 에 대해 수행되는 솔루션을 비교하는 벤치 마크 입니다.
$ time tar -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/ | wc -c
332308480
real 0m0.457s
user 0m0.064s
sys 0m0.772s
tarsize$ time ./tarsize.sh -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/
332308480
real 0m0.016s
user 0m0.004s
sys 0m0.008s
위의 코드, 위의 코드를 공유 라이브러리로 빌드하는 기본 빌드 스크립트 및이를 사용하는 ” LD_PRELOAD
기술” 스크립트가 리포지토리에 제공됩니다.
https://github.com/G4Vi/tarsize
LD_PRELOAD 사용에 대한 일부 정보 : https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/