🐧
duとwcの違い
duとwc
ファイルサイズを知りたい時に使うコマンドとして、du と wc がある。これらの違いは何だろう?
Ubuntu 18.04 LTS で GNU Coreutils の du と wc で確認する。
duは4096バイト単位に切り上げる...とは限らない
du は通常4096バイト単位に切り上げたサイズを返す。
$ echo -n 12345 > xxx
$ du xxx
4 xxx
$ du --block-size=1 xxx
4096 xxx
実装を確認すると、fstatat(2) で得られた stat 構造体から stat.st_blocks * 512
の値を返している。上の例だと st_blocks が8の倍数になっている。
duinfo_set (&dui,
(apparent_size
? MAX (0, sb->st_size)
: (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE), /* HERE */
(time_type == time_mtime ? get_stat_mtime (sb)
: time_type == time_atime ? get_stat_atime (sb)
: get_stat_ctime (sb)));
# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
/* ... */
# define ST_NBLOCKSIZE 512
一方で、-b
オプションをつけると、4096バイト単位に切り上げたサイズではなく、実際のファイルの中身のサイズが返ってくる。
$ echo -n 12345 > xxx
$ du -b xxx
5 xxx
したがって、duの出力が常に4096バイト単位に切り上げられるわけではない。
実装を確認すると、この場合には stat.st_size
の値を返している。
duinfo_set (&dui,
(apparent_size
? MAX (0, sb->st_size) /* HERE */
: (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
(time_type == time_mtime ? get_stat_mtime (sb)
: time_type == time_atime ? get_stat_atime (sb)
: get_stat_ctime (sb)));
wcはreadする...とは限らない
wcをオプションなしで実行すると、対象のファイルをreadし、lines、words、bytes を出力する。
$ echo -n 12345 > xxx
$ wc xxx
0 1 5 xxx
$ strace wc xxx 2>&1 >/dev/null
...
openat(AT_FDCWD, "xxx", O_RDONLY) = 3
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "12345", 16384) = 5
read(3, "", 16384) = 0
...
words, linesを取得するためにはファイルの内容を読み込む必要があるため。
一方、wc -c
で bytes のみを取得する場合はreadせずにサイズを返すという動きをする。
$ wc -c xxx
5 xxx
$ strace wc -c xxx 2>&1 >/dev/null
...
openat(AT_FDCWD, "xxx", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=5, ...}) = 0
...
fstat(2) で stat 構造体を取得し、stat.st_size
の値を返している。
duはファイルをopenしない
wc はファイルをオープンしてそのサイズを取得するが、du はファイルをオープンせずに fstatat(2) でサイズを取得する。
したがって、du だと読み取りアクセス許可が無いファイルのサイズも取得できるが、wc だとエラー(Permission denied)になる。
$ echo -n 12345 > xxx
$ chmod -r xxx
$ ls -l xxx
--w--w---- 1 vagrant vagrant 5 Mar 21 22:13 xxx
$ du -b xxx
5 xxx
$ wc -c xxx
wc: xxx: Permission denied
まとめ
- duは4096バイト単位に切り上げたサイズを返すこともあるが、そうじゃ無い場合もある。
- wcはファイルをreadすることもあるが、しないこともある。
- du はファイルをopenしない。wcはファイルをopenする。
Discussion