다른 곳에서 하드 링크되지 않은 파일이 사용한 공간 만 'du'하는 방법은 무엇입니까?


14

rsync --link-dest공간 절약형 스냅 샷에 사용하여 실제로 얼마나 많은 공간을 절약 했는지 어떻게 알 수 있습니까? 또는 더 일반적인 :

디렉토리 구조 외부 의 다른 곳에서 하드 링크되지 않은 파일 만 고려하여 디렉토리가 얼마나 많은 공간을 사용하는지 알아내는 방법은 무엇입니까? 다르게 질문 : 해당 디렉토리를 삭제 한 후 실제로 사용 가능한 공간이 얼마나됩니까? ( du -hs거짓말이다. 하드 링크 자체에 필요한 공간이 포함될 수있다)


2
기본적으로 GNU du-l/ --count-links옵션 을 사용하지 않으면 하드 링크 된 경우에도 파일 크기를 한 번만 계산합니다 . du이 옵션을 사용하거나 사용하지 않고 전체 트리에서 두 번 실행 하며 크기의 차이는 모든 디렉토리에서 저장 한 공간의 양이어야합니다.
jw013

답변:


9

내부 하드 링크가 없다고 가정하면 (즉, 하드 링크가 2 개 이상인 모든 파일이 트리 외부에서 링크 됨) 다음을 수행 할 수 있습니다.

find . -links -2 -print0 | du -c --files0-from=-

편집 여기 주석에서 스케치 한 내용이 적용됩니다. 없이 du; 눈치 채기 위해 @StephaneChazelas에 대한 조언 du은 필요하지 않습니다. 끝에 설명.

( find . -type d -printf '%k + ' ; \
  find . \! -type d -printf '%n\t%i\t%k\n' | \
    sort | uniq -c                         | \
    awk '$1 >= $2 { print $4 " +\\" }' ; \
  echo 0 ) | bc

우리가하는 일은 모든 관련 파일의 디스크 사용량 (KB)을 더하기 기호로 구분하여 문자열을 만드는 것입니다. 그런 다음에 큰 추가 내용을 제공 bc합니다.

첫 번째 find호출은 디렉토리에 대해 수행합니다.

두 번째 find는 링크 수, inode 및 디스크 사용량을 인쇄합니다. sort | uniq -c(트리의 모양 수, 링크 수, inode, 디스크 사용량) 목록을 얻기 위해 해당 목록을 전달합니다 .

목록을으로 전달 awk하고 첫 번째 필드 (#)가 두 번째 (하드 링크 #)보다 크거나 같으면 트리 외부에서이 파일에 대한 링크가 없다는 의미입니다. 더하기 부호와 백 슬래시가 첨부 된 디스크 사용량).

마지막으로 우리는 a를 출력 0하므로 수식은 구문 상 정확하고 ( +그렇지 않으면 en ) 전달합니다 bc. 휴

(그러나 충분한 대답을 제공한다면 더 간단한 첫 번째 방법을 사용합니다.)


고마워요, 그 요구 사항이 충족되면 작동합니다. 그러나 그렇지 않은 경우 어떻게해야합니까?
Tobias Kienzler

그것은 디렉토리 자체의 크기를 설명하지 못하기 때문에 작동하지 않습니다 (일반적으로 적어도 2 개의 링크가 있고 그렇지 않은 경우 파일이 두 번 계산됩니다).
Stéphane Chazelas

1
그런 다음 findinode 및 링크 수를 가진 모든 파일 목록을 인쇄하는 데 사용해야 합니다. 그런 다음 조합으로 sort | uniq -c트리에 각 inode가 몇 번 나타나는지 확인한 다음 링크 수보다 많은 링크 수를 가진 항목을 필터링하여 해당 목록을에 피드하십시오 du. 그러나 요구 사항이 충족되면 노력을 절약 할 수 있습니다.
angus

@StephaneChazelas 작동하지만 디렉토리 자체의 크기를 설명하지는 않습니다. 's 와 비슷한 매개 변수 만 du가지고 있다면 ...-dls
angus

또한 btrfs파일 시스템에서 디렉토리의 링크 수는 항상 1이므로 다음을 추가해야합니다.! -type d
Stéphane Chazelas

5

기본적으로 모든 파일 (비 디렉토리)에 대한 inode 번호와 링크 수를 가져와 해당 링크 수를 각 inode의 발생 수와 비교 한 다음 서로 다르면 파일을 제외해야합니다.

그것들이 모두 같은 파일 시스템에 있다고 가정하면 다음과 같이 작동합니다 (GNU 찾기 사용).

find . -type d -printf '%k\n' -o -printf '%i %n %k\n' |
   awk '
     NF==1{t+=$0; next}
     {n1[$1]=$2; n2[$1]++; s[$1]=$3}
     END {
       for (i in n1)
         if (n1[i] == n2[i])
           t+=s[i]
       print t
     }'

그래, 내가 말한 것 (신용에 감사드립니다). 그러나 디렉토리 수를 계산하면 얻을 수있는 정확도는 정확하지 않은 디스크 사용량을 추가하면 손실됩니다.
angus

@angus, "inexact 디스크 사용"은 무엇을 의미합니까?
Stéphane Chazelas

아무것도, 나는 %k보고 된 것에 대해 완전히 착각 했다. 훌륭 du합니다. 전혀 필요하지 않습니다! 집에 도착하면 답변을 업데이트하겠습니다. 감사!
angus

3

du actualy는 거짓말을하지 않을 것입니다;) 그것은 주어진 dir (s)을 파싱하고, 동일한 inode를 가리키는 모든 하드 링크 중 첫 번째 만 계산합니다.

du하나의 디렉토리에서만 보이는 것을 묻는다면 동일한 내용을 가리키는 다른 하드 링크가 있는지는 신경 쓰지 않습니다.

$ du -h daily.0 && du -hc daily.1
29G /daily.0
29G /daily.1

이제 동일한 행에 dirs를 제공하십시오 (rsync 증분 백업을위한 가장 최근의 것으로 시작 --link-dest).

$ du -hc daily.0 daily.1
29G /daily.0
364M /daily.1
29G total

또는 전체 백업 디렉토리 :

$ du -hc --max-depth=1 /snapshots
29G /daily.0
364M /daily.1
537M /daily.2
333M /daily.3
30G total

'daily.0'에서 이미 참조 된 inode (일명 "실제"파일)를 참조하는 'daily.1'의 파일은 계산되지 않습니다.

따라서 매일 삭제하면 1 장치에 364MB가 저장됩니다.

없애다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.