コマンド
chmod
ファイル・ディレクトリのパーミッション・属性を変更する。
UNIX/Linux の chmod コマンドは、ファイルやディレクトリのパーミッションや属性を変更するためのコマンドである。パーミッションにより、あるファイルを、どのユーザが読むことができ、どのユーザが書き込めるか、などのアクセス権限を管理している。
●パーミッションの確認方法
現在のパーミッションの値は ls -l で調べることができる。
% ls -l sample.dat
-rwxr-xr-- 1 user group 402 Oct 17 2018 sample.dat
の「-rwxr-xr--」がパーミッションである。
また、下記のように stat コマンドを使う手もある。stat コマンドなら「0754/-rwxr-xr--」と 8進数表記でも表示してくれるため、わかりやすいヵもしれない。
% stat sample.dat
File: sample.dat
Size: 402 Blocks: 8 IO Block: 4096 regular file
Device: 811h/2065d Inode: 21353 Links: 1
Access: (0754/-rwxr-xr--) Uid: ( 1001/user) Gid: ( 1001/group)
(略)
●パーミッションの概念の説明
基本的なパーミッションの概念を説明しよう。「rwxr-xr--」の読み方は、まずパーミッションの表示を3文字ごとに区切って、「rwx」「r-x」「r--」とする。
- 1番目のセクション (rwx) はファイル所有者 (この場合は user) にとってのパーミッション
- 2番目のセクション (r-x) はファイル所有グループ (この場合は group) にとってのパーミッション
- 3番目のセクション (r--) はそれ以外のユーザにとってのパーミッション
となる。「r」は読み込み可能属性、「w」は書き込み可能属性、「x」は実行可能属性を意味する。
つまり
-rwxr-xr-- 1 user group 402 May 26 2018 sample.dat
は、
- ユーザ user は、sample.dat を読めるし、書き込めるし、実行できる
- グループ group に属するユーザは、sample.dat を読めるし、実行できるが、書き込みはできない
- その他のユーザは、sample.dat を読めるが、書き込みと実行はできない
ということを意味する。
パーミッションの指定方法には絶対方式と相対方式がある。絶対方式は8進数の数字によって指定する。
- 0400 所有者が読み込める
- 0200 所有者が書き込める
- 0100 所有者が実行できる
- 0040 groupに属するユーザが読み込める
- 0020 groupに属するユーザが書き込める
- 0010 groupに属するユーザが実行できる
- 0004 その他のユーザが読み込める
- 0002 その他のユーザが書き込める
- 0001 その他のユーザが実行できる
また、この他に suid・sgid・sticky bit があるが、説明は後述。
ファイル sample.dat を所有者だけが読み込み・書き込みできるようにするには 0400+0200+0100=0700 で、
とする。ファイルsampleを所有者が読み込み・書き込み・実行できて、groupに属するユーザとその他のユーザは読み込み・実行のみできるようにするには、0400+0200+0100+0040+0010+0004+0001=0755 で
とする (最初の 0 を省略して 700・755 でもよい)。
一方、相対方式は、
- u,g,o,a … 所有者・グループに属するユーザ・その他のユーザ、全員
- r,w,x … 読み込み属性・書き込み属性・実行属性
- +/- … 属性を ON にする/OFF にする
を使う。これは現在のパーミッションの一部だけを変更する際に便利。
% chmod +x file
⇒ file の実行属性を ON にする
% chmod go-w file
⇒ file のグループとその他のユーザの書き込み属性を OFF にする
% chmod a-x file
⇒ file の全員の実行属性を OFF にする (chmod ugo-x file と同じ)
ただし、相対方式と言っても、
% chmod u=rwx,go=rx file (chmod 755 と同じ)
のように完全な (相対的でない) パーミッションを設定することはできる。
なお、シンボリックリンクのパーミッションは意味を持たない。
lrwxrwxrwx 1 user group 3 Aug 1 16:14 file-b -> file-a
でも
l--------- 1 user group 3 Aug 1 16:14 file-b -> file-a
でも全く違いはない。これはすべての UNIX/Liunx 共通のルールである。有効なのはリンク先の file-a のパーミッションである。chmod に -RH オプションを付けると、シンボリックリンクのリンク先のファイルの属性を変更する。
なお、chmod +x の場合、「誰の」パーミッションを変更するのかが気になるかもしれないが、答えは「umask の値で決まる」である。一般的には umask の値は 022 になっていると思われるので、chmod +x は chmod a+x と同じである。詳しくは umask の項を参照のこと。
●ディレクトリのパーミッション
これまで r(400)・w(200)・x(100) は読み込み・書き込み・実行属性であると説明してきたが、これはファイルに対する権限であって、ディレクトリに対しては意味が少し違い、
- r … そのディレクトリの下にあるファイルの一覧を取得できるかどうか
- w … そのディレクトリの下に、ファイルを新規作成できるかどうか。
また、そのディレクトリの下に存在するファイルを、消去できるかどうか。
- x … そのディレクトリの下にあるファイルにアクセスできるかどうか
という意味を持つ。
- ディレクトリに「r」が設定されていると、ls コマンドなどで、その下に存在するファイルの一覧を取得できる。具体的には、readdir(2) できる。
- ディレクトリに「w」が設定されていると、ディレクトリの下にファイルを新規作成できるし、ディレクトリの下に存在するファイルを rm コマンドで削除できる。具体的には、ディレクトリの下のファイル・ディレクトリに対して stat(2) や unlink(2) ができる。
- ディレクトリに「x」が設定されていると、その下のファイルの情報を見たり、ファイルに対して書き込み・読み込みができる
では実際に例を示そう。
% mkdir dir
% echo hogehoge > dir/file
% chmod 700 dir
ディレクトリ dir を作成し、その下にファイル file を作成する。file の中身は「hogehoge」である。
% ls dir
file
⇒ ディレクトリ dir 下のファイル一覧が取得できる
% ls -l dir
-rw-r--r-- 1 user group 9 Oct 10 14:57 file
⇒ ディレクトリ dir 下のファイルの情報が取得できる
% ls -l dir/file
-rw-r--r-- 1 user group 9 Oct 10 14:57 file
⇒ ファイル名を直接指定しても大丈夫
% cat dir/file
hogehoge
⇒ ディレクトリ dir 下のファイルの内容が取得できる
いずれも普通にアクセスできることがおわかりだろう。
では、ディレクトリ dir のパーミッション「r」だけを立てて、同じことをしてみよう。
% chmod 400 dir
% ls dir
file
⇒ ディレクトリ dir 下のファイル一覧が取得できる
% ls -l dir
ls: dir/file: Permission denied
⇒ ディレクトリ dir 下のファイルの情報は取得できない
% ls -l dir/file
⇒ ファイル名を直接指定してもダメ
% cat dir/file
cat: dir/file: Permission denied
⇒ ディレクトリ dir 下のファイルの内容が取得できない
ls で dir の下のファイル一覧は取得できるが、ls -l で各ファイルの情報を取得することはできない。dir の下のファイルを表示することもできない。
次に、ディレクトリ dir のパーミッション「x」だけを立てて、同じことをしてみよう。
% chmod 100 dir
% ls dir
ls: dir: Permission denied
⇒ ディレクトリ dir 下のファイル一覧は取得できない
% ls -l dir
ls: dir: Permission denied
⇒ ディレクトリ dir 下のファイルの情報も取得できない
% ls -l dir/file
-rw-r--r-- 1 user group 9 Oct 10 14:57 file
⇒ ファイル名を直接指定すれば大丈夫
% cat dir/file
hogehoge
⇒ ディレクトリ dir 下のファイルの内容は取得できる
「r」を落として「x」を立てると、ls で dir の下のファイル一覧が取得できなくなった。しかしファイル名を直接指定すると、ls -l も有効だし、ファイルの内容も表示できる。
普通、ディレクトリは他ユーザに対して「r-x」としておけばよい。もしディレクトリの下にアクセスしてほしくなければ「---」にすればよいだろう。「r」だけにすると、ファイル一覧は取得できるが、そのファイルの情報を見たり、ファイルにアクセスすることはできなくなる。一方「x」だけを立てると、ファイル一覧は取得できないが、ファイルにアクセスすることはできる、というわけだ。
●ファイルに対する setuid・setgid
さて、先に少し触れたが、
4000 user s-bit を立てる (setuid・suid)
2000 group s-bitを立てる (setgid・sgid)
1000 sticky bit を立てる
というものがある。
あるいは
で setuid を立てることができ、
あるいは
で setgid を立てられる。setuid・setgid の意味については setuid の項を参照してほしい。
例として、CVS で新規ファイルを add した場合の挙動を考えよう。userA と userB のグループが以下のとおりであるとする。
- userA のプライマリグループ: groupA、その他のグループ: cvs
- userB のプライマリグループ: groupB、その他のグループ: cvs
そして以下のように、ディレクトリ dir/ のグループが cvs、パーミッションが 775 だとしよう。
drwxrwxr-x 2 userA cvs 117 7月 31日 19:20 dir/
ここで userB が dir/ の下に新たなファイル・ディレクトリを作成したとき、新規ファイルのグループはどうなるだろうか。これは OS によって結果が異なる (CVS に特化した話ではなく、UNIX 一般の話である)。
●BSD 系 UNIX の場合
drwxrwxr-x 2 userB cvs 100 7月 31日 19:25 dir/newfile.txt
⇒ 上位ディレクトリ (dir/) のグループ cvs を引き継ぐ
●SystemV 系 UNIX の場合
drwxrwxr-x 2 userB groupB 100 7月 31日 19:25 dir/newfile.txt
⇒ 作成者 (userB) のプライマリグループ groupB がセットされる
CVS を利用する上で好ましいのは BSD 系 UNIX の方である。なぜなら、新規ファイルのグループが cvs となるため、userB が追加した dir/newfile.txt を userA が編集することができるからだ。一方、SystemV 系 UNIX の場合は、userB が作成したファイルを修正できるのは userB だけになってしまう。
ただし SystemV 系 UNIX でも BSD と同様の挙動をさせる方法がある。それがディレクトリに対して setgid ビットを立てる方法である。このビットを立てておくと、BSD と同様に新規ファイル・ディレクトリの作成時に上位ディレクトリのグループを引き継ぐようになる。setgid ビットが立っているかどうかは、パーミッションが「drwrsx」となっていることで確認できる。
% ls -ld dir
drwxrsxr-x 2 userA cvs 117 7月 31日 19:20 dir/
ちなみに Linux ではデフォルトは SystemV 系 UNIX と同じ動作をするが (setgid についても同様)、mount のオプションで BSD と同じ挙動をさせることができる (grpid または bsdgroups)。
●sticky bit
sticky bit というのは、ディレクトリの下にあるファイルの削除に関する設定である。例えば /tmp ディレクトリを考えてみよう。/tmp は一時ファイルを作成するためのディレクトリで、誰でもファイル・ディレクトリを作成できる。しかし /tmp のパーミッションを 777 にすると、あるユーザが作ったファイルを他のユーザが消すことができてしまう。そこで /tmp のパーミッションを 777 にし、さらに sticky bit を立てる。すると、
- 誰でもそのディレクトリの下にファイル・ディレクトリを新規作成できる
- しかし、それを消せるのは作成したユーザ (ファイル・ディレクトリのオーナー) のみ
となる。実際、/tmp は sticky bit が立っている。
% ls -ld /tmp
drwxrwxrwt 7 bin bin 1024 Oct 10 10:24 /tmp
最後の「rwt」の「t」が sticky bit を表している。
% chmod 1777 dir
% chmod a+rwxt dir
などで sticky bit を ON にできる。
昔の UNIX の sticky bit というのは、実行ファイルに対して設定するものであった。頻繁に使用するプログラムについて このビットを立てておくと、常にメモリ上にバイナリを保存しておく効果があった。しかし今では仮想記憶の発達により、意味をなさなくなったので、ファイルに対してこのビットを立てても無視される。「sticky」は「貼り付けておく」という意味であるが、現在では「sticky」という意味はなく、名前だけが残っているわけである。
●ファイルフラグ
なお、BSD 系 UNIX には、chmod のパーミッションとは全く別に、ファイルフラグという概念がある。これは chflags コマンドで設定できる。
読み方
chmod
(UNIXコマンド) [ちぇんじ・もーど] [しー・えっち・もーど] [ちもど] [ちもっど] [ちぇもど]
"CHange MODe" の略。これの読み方は難しい。素直に略さず [ちぇんじ・もーど] というのが無難かもしれない。しかし [ちもど] と読む人がいたのにはびっくりした。