[linux] 쉘에서 파일 크기 (바이트)를 가져 오는 이식 가능한 방법?

Linux에서는 stat --format="%s" FILE 하지만 Solaris에 액세스 할 수있는 stat 명령이 없습니다. 그러면 무엇을 사용해야합니까?

Bash 스크립트를 작성 중이며 실제로 시스템에 새로운 소프트웨어를 설치할 수 없습니다.

이미 다음을 사용하고 있습니다.

perl -e '@x=stat(shift);print $x[7]' FILE

또는:

ls -nl FILE | awk '{print $5}'

그러나 이것들 중 어느 것도 합리적이지 않은 것 같습니다. 파일 크기를 얻기 위해 Perl을 실행합니까? 아니면 동일한 작업을 수행하기 위해 2 개의 명령을 실행합니까?



답변

wc -c < filename(단어 수의 약어 -c, 바이트 수를 인쇄 함)은 이식 가능한 POSIX 솔루션입니다. 일부 공백이 앞에 추가 될 수 있으므로 출력 형식 만 플랫폼간에 균일하지 않을 수 있습니다 (Solaris의 경우).

입력 리디렉션을 생략하지 마십시오. 파일이 인수로 전달되면 파일 이름이 바이트 수 뒤에 인쇄됩니다.

바이너리 파일에서는 작동하지 않을까 걱정했지만 Linux와 Solaris 모두에서 정상적으로 작동합니다. 으로 시도해 볼 수 있습니다 wc -c < /usr/bin/wc. 또한 POSIX 유틸리티는 별도로 명시하지 않는 한 바이너리 파일을 처리하도록 보장됩니다 .


답변

나는 크기를 표시하기 위해 내 자신의 프로그램 (정말 작은)을 작성했습니다. 자세한 정보 : http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html

일반적인 Linux 도구를 사용하는 가장 깨끗한 두 가지 방법은 다음과 같습니다.

$ stat -c %s /usr/bin/stat
50000

$ wc -c < /usr/bin/wc
36912

그러나 파일 크기를 얻기 위해 매개 변수를 입력하거나 출력을 파이프하고 싶지 않으므로 내 bfsize를 사용하고 있습니다.


답변

du일반적으로 실제 데이터 크기가 아닌 디스크 사용량을 인쇄 하지만 GNU coreutils du는 파일의 “명백한 크기”를 바이트 단위로 인쇄 할 수 있습니다.

du -b FILE

그러나 BSD, Solaris, macOS 등에서는 작동하지 않습니다.


답변

마지막으로 ls 및 bash 배열 확장을 사용하기로 결정했습니다.

TEMP=( $( ls -ln FILE ) )
SIZE=${TEMP[4]}

별로 좋지는 않지만 적어도 하나의 fork + execve 만 수행하고 보조 프로그래밍 언어 (perl / ruby ​​/ python / whatever)에 의존하지 않습니다.


답변

크로스 플랫폼 가장 빠른 솔루션 ( ls 에 대해 단일 fork () 만 사용하고 실제 문자를 계산하지 않으며 불필요한 awk, perl 등을 생성하지 않음).

MacOS, Linux에서 테스트 됨-Solaris의 경우 약간의 수정이 필요할 수 있습니다.

__ln=( $( ls -Lon "$1" ) )
__size=${__ln[3]}
echo "Size is: $__size bytes"

필요한 경우 ls 인수를 단순화 하고 $ {__ ln [3]}에서 오프셋을 조정합니다.

참고 : 심볼릭 링크를 따릅니다.


답변

BSD는 statGNU coreutils와 다른 옵션을 가지고 있지만 비슷한 기능을 가지고 있습니다.

stat -f %z <file name> 

이것은 macOS (10.12에서 테스트 됨), FreeBSD , NetBSDOpenBSD에서 작동 합니다.


답변

ls -n출력을 처리 할 때 잘못 이식 할 수있는 쉘 배열의 대안으로 유일한 배열을 형성하고 표준 쉘의 유일한 지역 변수 인 위치 인수를 사용할 수 있습니다. 스크립트 또는 함수에 대한 원래 인수를 유지하려면 함수에서 위치 인수 덮어 쓰기를 래핑합니다.

getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE

ln -dn현재 IFS환경 변수 설정 에 따라 의 출력을 분할하고 위치 인수에 할당하고 다섯 번째 인수를 에코합니다. 는 에서와 달리 -d디렉토리가 올바르게 처리되고 -n사용자 및 그룹 이름을 확인할 필요가 없음을 보장합니다 -l. 또한 공백이 포함 된 사용자 및 그룹 이름은 이론적으로 예상되는 줄 구조를 깨뜨릴 수 있습니다. 일반적으로 허용되지 않지만 이러한 가능성은 여전히 ​​프로그래머를 멈추고 생각하게 만듭니다.