Open Groupの仕様によると、POSIXはdu
-b
サイズをバイト単位で表示するオプションはありません。それでは、ファイルやフォルダのサイズをバイト単位で取得するPOSIX互換の方法は何ですか?
ベストアンサー1
du
GNUが何をしているのかを概説する-sb
と、次のようになります。
cumulative_size() (
export LC_ALL=C
ret=0
[ "$#" -gt 0 ] || set .
for file do
case $file in
(/*) sanitized=$file;;
(*) sanitized=./$file;;
esac
size=$(
find "$sanitized" ! -type b ! -type c -exec ls -niqd {} + |
awk '! seen[$1]++ {sum += $6}
END {print sum}'
)
if [ -n "$size" ]; then
printf '%s\t%s\n' "$size" "$file"
else
ret=1
fi
done
exit "$ret"
)
GNUと同様に、du
ファイルのinode番号を見てls -ni
ファイル数を1回だけ計算しようとします(最初のフィールドに報告されているように)。デバイスIDls
ディレクトリ階層が複数のファイルシステムにまたがっていないと仮定して報告することはできません。
これとは対照的に、ファイル固有のdu
パラメータからのみ重複を削除します。
たとえば、
cumulative_size dir dir
の累積ディスク使用量とその内容はdir
2回報告され、ファイル内の各ファイルは一度だけ計算されますが、GNUはディスク使用量を1回だけ報告du -bs
します。dir
デバイスファイルls -n
のサイズは報告されていないため除外します。少なくともLinuxでは、サイズは常に0
。
find
述部で始まるファイル、または-
その述部と一致する名前で始まるファイルパスは提供できません(!
、...も含む)。(
ここでは、ファイルパスが./
で始まらない場合はプレフィックスを追加してこの問題を解決します/
。したがって、はまたはにfind !
なりfind -print
ます。で始まる述語が実装にないとします。これは、オプションの終わりを示すためにに渡す必要がないことを意味します。find ./!
find ./-print
find
/
--
ls
uid / gidをユーザー名またはグループ名にデコードすることは避けls -n
ませんls -l
(これは費用がかかり、スペースがある名前に問題を引き起こします)。 POSIXはこれらのフィールドを完全に削除するために-o
/オプションを指定します-g
が、オプションです。
の出力はls -n
C / POSIXロケールでのみ指定されます。さらに、ファイルパスはnullではなくバイトの任意のシーケンスであり、Cロケールではテキストとしてのみ処理できるためLC_ALL=C
。
また、-q
ファイル名やシンボリックリンク先の改行が問題を引き起こさないようにするためにも使用します。
また、パス全体がに渡されるため、パスのls
長さがPATH_MAXを超えると動作が停止するため、任意の深さのディレクトリ構造を処理できません。
バグ報告はかなり荒いです。計算されたサイズがnullを返す場合にのみ、ゼロ以外の終了ステータスを報告します。したがって、終了状態が0であっても、すべてのファイルサイズが考慮されたことを保証するわけではありません。