chownコマンドに-Rオプションを付けたときの動きを調べてみた

Linuxで遊んでるときに、「chown -R foo:bar / をもし実行したら、どんな動きで権限が変更されていくんだろう?」とちょっと気になったので調べてみました。特に、ディレクトリの探索順序がどうなってるのか興味があります。幅優先、深さ優先、どっちなんだろう?

まずはmanを確認

最初に、manのオプションの説明を見てみることにしました。

  • Rオプションの説明には、このように書いてありました(chownのmanから抜粋)。

オプション:

  • R, --recursive

ファイルやディレクトリの所有権を再帰的に変更する。

Man page of CHOWN

とってもあっさり。ここではディレクトリの辿り方までは分かりませんでした。

manじゃ分からなかったからソースコードを読んでみた

ググって分かりそうなことでもないし、これはいっそソースコードを読んだらいいんじゃない?!ということでソースを見てみました。

GNUのダウンロードサイトからソースをダウンロードします。chownコマンドのソースは、coreutilsとして他のコマンドと一緒にまとめられています。一緒に入ってるコマンドは、rm、kill、lsなど。

このサイトから一番新しいバージョンのtarballをダウンロードして、展開します。
その中にsrcディレクトリがあって、ソースが入っています。

中身はこんな感じです。

$ tree coreutils-8.9/src/
coreutils-8.9/src/
├── Makefile.am
├── Makefile.in
├── base64.c
├── basename.c
├── c99-to-c89.diff
├── cat.c
├── chcon.c
├── chgrp.c
├── chmod.c
├── chown-core.c
├── chown-core.h
├── chown.c
(略)

chown.cを見てみる

chown.cを見てみると、コマンドオプションを読み取って処理の振り分けをしているようでした。そして振り分けが終わったあとに、chown_filesという関数が呼び出されています。実際の処理はchown_files関数で行われているようです。

そしてchown-core.cへ

chown_files関数は、chown-core.cで定義されていました。chown-core.cでchown_files関数を読んでみると、ここでは内部的にfts_read関数が呼び出されていて、これがファイルを辿る役割をしていました。

さらにfts.cへ

fts_read関数はライブラリのfts.cで定義されています。fts.cは、ファイルの階層を探索するためのライブラリです。

fts_read関数では、与えられたディレクトリの中身を全部辿る→全部辿り終わったら子要素のディレクトリを辿る という流れで処理が行われていると分かりました。

結論

chownコマンドに-Rオプションを付けると、幅優先でディレクトリを探索することがわかった!


つまり、例えばroot権限で chown -R foo:var / を実行したら/(ルートディレクトリ)そのものから順番に、階層が浅いものからファイルの所有者や所有グループが変更されていく、ということになります。


分かるまでなかなか長い道のりだったー。でもおもしろかった。