macOS: du가 잘못된 디스크 사용량을 보고할 가능성이 있습니까?

macOS: du가 잘못된 디스크 사용량을 보고할 가능성이 있습니까?

내 볼륨의 특정 위치에서 테스트 중인 스크립트가 있는데 그 일부는 디스크 사용량과 총 데이터 크기를 계산하는 것입니다. 모든 것이 괜찮습니다. 내가 얻는 값은 mdlsmacOS 자체가 출력 및 Finder 정보에서 보고하는 값과 항상 일치합니다.

그런데 Homebrew 설치 디렉터리에서 스크립트를 실행하면 /usr/local/Cellar출력이 이상합니다. 디스크 사용량은 3,234,828,288바이트 단위이지만 데이터 크기는 실제로 더 큰 단위입니다 3,254,656,870. 루트로 스크립트를 실행하거나 GNU-du를 사용할 때 동일한 결과를 얻습니다. 디스크 사용량이 항상 데이터 크기보다 높아야 하지 않나요? (물론 HFS+ 압축을 사용하지 않는 한, 여기서는 그렇지 않은 것 같습니다. 출력에 "압축" 파일 플래그가 없습니다 ls.)

다음은 스크립트의 관련 부분입니다. 먼저 디스크 사용량과 총 데이터를 표시합니다.

FILEPATH="/usr/local/Cellar"
DISK_USAGE=$(/usr/bin/du -k -d 0 "$FILEPATH" | /usr/bin/head -n 1 | /usr/bin/awk '{print $1}')
DU_SIZE=$(echo "$DISK_USAGE * 1024" | /usr/bin/bc -l)
SEDPATH=$(echo "$FILEPATH" | /usr/bin/awk '{gsub("/","\\/");print}')
LISTING=$(ls -RAlO@ "$FILEPATH" | /usr/bin/sed -e '/^$/d' -e '/^'"$SEDPATH"'/d' | /usr/bin/awk 'NF>2')
DATASIZE=$(echo "$LISTING" | /usr/bin/grep -v '^d' | /usr/bin/awk '{total += $6} END {printf "%.0f", total}')
echo "du: $DU_SIZE"
echo "data: $DATASIZE"

가능한 해결책:macOS와 HFS+가 문제입니다.언제나처럼! 나는 그것을 "사과 핵심 썩음"이라고 부른다고 생각합니다. 전체 데이터 크기를 계산하는 스크립트와 함께 du 명령을 다시 실행하고 ls/stat 출력의 블록 수를 기반으로 디스크 사용량을 "수동으로" 계산하는 몇 가지 명령을 추가했습니다. 디스크 사용량은 실제로 전체 데이터 크기보다 컸습니다. FS 압축(스파스 파일 등)이 없어야 하기 때문입니다. 이제 (갑자기!) du 명령도 올바른 결과를 출력합니다. 추측만 할 수 있는 이유는 아마도 HFS+가 처음에 이를 계산할 시간이 없었기 때문일 것입니다. 따라서 du가 시스템에 "디스크 사용량이 무엇인지" 물었을 때 부분적인 결과만 얻었습니다.

FILEPATH="/usr/local/bin"                                                                                                     [21:38:27]
SEDPATH=$(echo "$FILEPATH" | /usr/bin/awk '{gsub("/","\\/");print}')
MPOINT=$(/bin/df "$FILEPATH" | /usr/bin/tail -1 | /usr/bin/awk '{for(i=9; i<=NF; i++) printf "%s",$i (i==NF?ORS:OFS)}')
CLUSTERSIZE=$(/usr/sbin/diskutil info "$MPOINT" | /usr/bin/awk '/Device Block Size/{print $4}')
TOTAL_LIST=$(ls -ReAlOs@ "$FILEPATH")
SWITCH_LIST=$(echo "$TOTAL_LIST" | /usr/bin/sed -e '/^$/d' -e '/^'"$SEDPATH"'/d' | /usr/bin/awk 'NF>=11' | /usr/bin/awk '{print $2,$7,$1}')
BLOCKSONDISK=$(echo "$SWITCH_LIST" | /usr/bin/grep -v '^d' | /usr/bin/awk '{total += $3} END {printf "%.0f", total}')
SIZEONDISK=$(echo "$BLOCKSONDISK * $CLUSTERSIZE" | /usr/bin/bc -l)
echo "od: $SIZEONDISK B"
DISK_USAGE=$(/usr/bin/du -k -d 0 "$FILEPATH" | /usr/bin/head -n 1 | /usr/bin/awk '{print $1}')
DU_SIZE=$(echo "$DISK_USAGE * 1024" | /usr/bin/bc -l)
echo "du: $DU_SIZE B"
DATASIZE=$(echo "$SWITCH_LIST" | /usr/bin/grep -v '^d' | /usr/bin/awk '{total += $2} END {printf "%.0f", total}')
echo "ds: $DATASIZE B"

산출:

physical (stat): 36343808 B
physical   (du): 36343808 B
datasize (stat): 32584254 B

관련 정보