ファイルまたはフォルダのサイズをバイト単位で取得するPOSIX互換の方法は何ですか?

ファイルまたはフォルダのサイズをバイト単位で取得するPOSIX互換の方法は何ですか?

Open Groupの仕様によると、POSIXはdu-bサイズをバイト単位で表示するオプションはありません。それでは、ファイルやフォルダのサイズをバイト単位で取得するPOSIX互換の方法は何ですか?

ベストアンサー1

duGNUが何をしているのかを概説する-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

の累積ディスク使用量とその内容はdir2回報告され、ファイル内の各ファイルは一度だけ計算されますが、GNUはディスク使用量を1回だけ報告du -bsします。dir

デバイスファイルls -nのサイズは報告されていないため除外します。少なくともLinuxでは、サイズは常に0

find述部で始まるファイル、または-その述部と一致する名前で始まるファイルパスは提供できません(!、...も含む)。(ここでは、ファイルパスが./で始まらない場合はプレフィックスを追加してこの問題を解決します/。したがって、はまたはにfind !なりfind -printます。で始まる述語が実装にないとします。これは、オプションの終わりを示すためにに渡す必要がないことを意味します。find ./!find ./-printfind/--ls

uid / gidをユーザー名またはグループ名にデコードすることは避けls -nませんls -l(これは費用がかかり、スペースがある名前に問題を引き起こします)。 POSIXはこれらのフィールドを完全に削除するために-o/オプションを指定します-gが、オプションです。

の出力はls -nC / POSIXロケールでのみ指定されます。さらに、ファイルパスはnullではなくバイトの任意のシーケンスであり、Cロケールではテキストとしてのみ処理できるためLC_ALL=C

また、-qファイル名やシンボリックリンク先の改行が問題を引き起こさないようにするためにも使用します。

また、パス全体がに渡されるため、パスのls長さがPATH_MAXを超えると動作が停止するため、任意の深さのディレクトリ構造を処理できません。

バグ報告はかなり荒いです。計算されたサイズがnullを返す場合にのみ、ゼロ以外の終了ステータスを報告します。したがって、終了状態が0であっても、すべてのファイルサイズが考慮されたことを保証するわけではありません。

おすすめ記事