最低限 Unix / Linux [II] 【2. パーミッション】

  1. 事前準備
  1. パーミッション
  1. シェル
  1. テキストエディタ
  1. シェルスクリプト
  1. 本日の課題
情報実験第 3 回トップへ

本日最初の実習は, レクチャーで学んだ「パーミッション」についてです. レクチャーで示したとおり, パーミッションとは「ファイル/ディレクトリの利用権限」のことであり, そのファイルについて「誰が」「何を」していいのかを記述したものです. 実習では, パーミッションの確認及び操作, そして具体的なファイル保護の実践を行います.

[2-1] パーミッションを確認する

本節ではファイルの利用許可がどのように設定されているかを, 具体例を見ながら確認してみましょう.

[2-1-1] /home/$username

まずは, 前回の実習で作成したファイルのパーミッションを確認してみましょう.

  1. 自分の home 領域に移動します.
    $ cd /home/$username
    
  2. ls コマンドで home 領域に何があるかを確認します.
    $ ls
    ichigo.txt mikan ringo.jpg ...
    
  3. ls コマンドに -l オプションを付けて詳細情報まで表示させます.
    $ ls -l
    合計 60
    -rw-r--r-- 1 $username $username       23 2011-02-17 03:26 ichigo.txt
    drwxr-xr-x 7 $username $username     4096 2011-04-13 13:28 mikan
    -rwxr-xr-x 1 $username $username    53618 2011-06-13 19:07 ringo.jpg
    .
    .
    .
    

多少の差異はあると思いますが, 概ね似たような表示が現れるでしょう. ここで表示される情報のうち本実習で注目するのはスペースで区切られたカラムのうち 1 列目および 3, 4 列目です. 他の項目については付録にて詳しく取り上げています.

ファイルモード

1 列目の 10 文字(-rwxr-xr-x 等)はまとめてファイルモードとよばれます. ファイルモードのうち, 左端の 1 文字がファイルタイプを表し, 残りの 9 文字がパーミッションを表しています.

ファイルタイプ

ファイルタイプはその名のとおりファイルのタイプを表しています. 上の例では「-」と「d」の 2 種類が見られますが, これはそれぞれ「通常のファイル」と「ディレクトリ」を表します. みなさんが今後接するファイルはほとんどがこのいずれかのファイルタイプです. それ以外のファイルタイプについては付録を参照してください.

パーミッション

パーミッションは 9 文字で表現されていますが, 左から読み取り権限(Read), 書き込み権限(Write), 実行権限(eXecute)の有無を 1 文字で 表しており, それが 3 セットでそれぞれファイルの所有者(User), ファイルの所有グループ(Group), それ以外(Others)の 3 者に対する権限を示しています.

ここまでをまとめると次のようになります.

  d rwx r-x r-x
  ^ ^^^ ^^^ ^^^
  |  |   |   |
  |  |   |   アザーズパーミッション
  |  |   |
  |  |   グループパーミッション
  |  |
  |  ユーザーパーミッション
  |
  ファイルタイプ

・ファイル所有者(User)

ファイルの持ち主です. 基本的にはファイルを作った人が該当します. ファイル所有者のアカウント名はファイル情報の 3 列目に書かれています.

・ファイル所有グループ(Group)

ファイルを所有しているグループです. 基本的にはファイルを作った人のグループが そのまま適用されます. 複数のユーザでファイルを管理する場合, それらのユーザをグループアカウント(後述)に 登録したうえでファイルの所有グループ名をそのグループアカウントに設定すれば, 共用管理が可能になります. ファイル所有グループのグループアカウント名はファイル情報の 4 列目に書かれています.

・その他のユーザ(Other)

上記に当てはまらない(3, 4 列目に表示されていない)全てのユーザがこれに該当します.

・読み取り権限(Read)

ファイルの内容を読み取る権限です. このパーミッションがないアカウントでは, そのファイルを 開くことができません.

・書き込み権限(Write)

ファイルに内容を追記する権限です. このパーミッションがないアカウントでは, そのファイルを 編集できません.

・実行権限(eXecute)

ファイルを使う権限です. このパーミッションがないアカウントでは, そのファイルを使うことが できません.


ただし, それぞれの権限が具体的にどのような動作を指すのかは, ファイルタイプによって定義が異なります. ファイルタイプがディレクトリの場合は, RWX がそれぞれ「ディレクトリの中身を確認する」「ディレクトリ内のファイルを追加/削除する」 「ディレクトリを開く」に該当します.

ホーム領域にあるファイルは基本的には自分が作ったものですので, ファイル所有者は自分であり, ファイル所有グループも「自分一人」というグループになっています.

[2-1-2] /etc/

続いては各種の設定ファイルが格納されている /etc/ ディレクトリを確認してみましょう.

  1. /etc/ に移動します.
    $ cd /etc/
    
  2. ls コマンドに -l オプションを付けてディレクトリの中身を表示させます.
    $ ls -l
    .
    .
    .
    -rw-r--r-- 1 root root    2986 2011-01-20 15:42 adduser.conf
    -rw-r--r-- 1 root root      46 2012-04-19 20:52 adjtime
    -rw-r--r-- 1 root root     198 2011-01-20 16:04 aliases
    drwxr-xr-x 2 root root    4096 2012-04-19 18:28 alternatives
    -rw-r--r-- 1 root root     395 2008-03-10 04:58 anacrontab
    drwxr-xr-x 2 root root    4096 2012-03-06 11:39 anthy
    drwxr-xr-x 3 root root    4096 2012-03-05 21:09 apache2
    drwxr-xr-x 7 root root    4096 2012-03-05 20:48 apm
    drwxr-xr-x 6 root root    4096 2012-03-05 21:05 apt
    -rw-r----- 1 root daemon   144 2008-10-20 14:34 at.deny
    drwxr-xr-x 3 root root    4096 2012-03-06 11:37 avahi
    -rw-r--r-- 1 root root    1657 2010-04-10 21:03 bash.bashrc
    -rw-r--r-- 1 root root   57063 2010-11-16 17:08 bash_completion
    .
    .
    .
    

たくさんのファイルが表示されると思いますが, それらのファイル所有者は 原則として root になっています. よって, 一般のユーザ(Others)はこれらのファイルを読み取る(Read)ことはできますが 書き変える(Write)はできません. こうすることで, あくまで計算機全体の運用については計算機管理者(root)のみが 権限を持ち, 一般のユーザは自分の許される範囲でのみ計算機を利用できるという システムが維持されています.

[2-2] パーミッションを操作する

本節では, ファイルの利用権限をどのように変更するのか, 実際に操作してみましょう

パーミッションの変更には chmod (change mode)コマンドを使用します. このコマンドの使い方は以下のとおりです.


$ chmod (パーミッションの変更内容) (対象ファイル名)

パーミッションの変更内容の書式は 2 種類あり, ユーザ種別を表すアルファベット(u, g, o)に, 権限種別を表すアルファベット(r, w, x)を足し引き(+, -)する方法と, 各権限を意味する数字(r=4, w=2, x=1)の 和を 3 つ並べる方法があります. 後者の方は全てのユーザに対する権限を手軽にまとめて設定できるので便利です.

具体例1)
$ chmod g+w ichigo.txt
===== ichigo.txt の所有グループに書き込み権限を付与

具体例2)
$ chmod 750 ichigo.txt
      ichigo.txt の所有ユーザに読み取り/書き込み/実行権限, 
===== 所有グループに読み取り/実行権限 をそれぞれ与え, 
      その他のユーザには権限を与えない.

それでは実際に目的を設定し, それに応じたパーミッションを設定してみましょう.

ファイルとディレクトリの作成

まずは各端末で以下の作業をしてディレクトリとファイルを作成してください.

$ cd
$ mkdir secret
$ echo 'secret-word' > ./secret/word.txt

$ chmod ??? secret 

$ chmod ??? secret/word.txt 

< ホームディレクトリに移動.
< secret ディレクトリを作成.
< 'secret-word' 部分は好きな単語に置き換える. 
    secret ディレクトリの中に ファイルを作成. 
< chmod をつかって secret ディレクトリのパーミッションを変える.
    ファイルが相方から見えないように ??? の部分を考えよう. 
< chmod をつかって secret/word.txt ファイルのパーミッションを変える.
    上と同様にファイルが相方から見えないよう ??? の部分を考える. 

互いのファイルを覗いてみる

お互いに相手の word.txt ファイルを見てみましょう.

$ cat ~$username/secret/word.txt

お互いに相手のファイルが見えなければ成功です. もし見られてしまった場合は, 先の chmod コマンドを 先程とは違うモードで再度実行し, 見られない様にしてください.

見られないようにする方法がわかったら, 今度はいろいろな パーミッションにしてその違いを確かめてください. ディレクトリのパーミッションを変えると, そのディレクトリに移動できなくなったり するはずです. cd コマンドなどを試してみてください.

最後に自分の作った word.txt を消去してください. このとき, どのようなモードだとファイル消去できないかも是非試してください.


問題: word.txt もしくはディレクトリ secret のモードを変更し, secret/word.txt ファイルが消去できないようにせよ.

この知識は自分の卒論などを誤って消してしまわないためにも重要です! つまり, 消去できないようにファイルのモードを変更しておけば, 誤って rm コマンドを実行しそうになったときも, 消去されずに済むわけです!

UNIX / Linux ではファイルモードの設定によって, 他人のファイルを見る ことが可能です. 大抵の場合, 普通に作成したファイルは他人が見れる状態にあるでしょう. もし, 本当に見られては困る内容のファイルはモードを正しい設定にするように 心がけましょう. 他人がみても良い設定のファイルは基本的に "見ても良い" 訳ですが, "mail" といった文字列のつく名前のファイルやディレクトリの中, あるいは個人的な情報であることが推測できるファイルは, 仮に見れる状態にあっても絶対に見てはいけません. また, 同様に見られては困るファイルを見れる状態で置いておくことも 避けましょう. こういったファイルは, 見た方も見られた方も嫌な思いをしてしまいます.

次へ >>(シェル)

[2-3] 付録

本節では, ファイルモードの詳細や, ls -l コマンドで表示される他の項目について説明します.

・ファイルモード

自分のホームディレクトリで ls コマンドを幾つかのオプションを指定して 実行すると, 例えば以下のような出力が得られます.

$ ls -Flag
total 36
drwxr-xr-x 3 foo      4096 Apr 27 18:45 ./
drwxr-xr-x 3 root     4096 Apr  6 18:47 ../
-rw------- 1 foo       371 Apr 27 11:41 .bash_history
-rw-r--r-- 1 foo       220 Apr  6 18:47 .bash_logout
-rw-r--r-- 1 foo      3198 Apr  7 18:15 .bashrc
-rw-r--r-- 1 foo      3184 Apr  6 18:47 .bashrc~
drwxr-xr-x 3 foo      4096 Apr  7 18:16 .emacs.d/
-rw-r--r-- 1 foo       675 Apr  6 18:47 .profile
-rw-r--r-- 1 foo         9 Apr 27 18:45 hoge.txt
drwxr-xr-x 2 foo      4096 Apr 27 18:49 work/

この出力の下から 2 行目を例に取って, この読み方を解説します. 左から順に,

-rw-r--r-- ファイルモード
1 ファイルへの"リンク数"
foo ファイルの所有者
9 ファイルの大きさ(バイト単位)
Apr 27 18:45 ファイルの最終更新時刻
hoge.txt ファイルの名前

を表しています. これらをファイルの「属性」と呼びます (なお,
$ man ls


としてみるとより詳しいことが分かります).

一番左側の表示の文字列はファイルの「モード」, すなわち ファイルの型 (type) と利用権限 (permission) を表しています. 例えば, hoge.txt のすぐ下の work/ を見ると,

d rwx r-x r-x

と書かれてあります.

左端の1文字はファイルの型を示します. 取りうる文字と型は後述します.

続く文字列で利用権限を示しています. 利用権限の許可対象には,

があり, それぞれに対する許可情報を,

と読んでいます.

また利用権限には,


の 3 種類があります. ファイルモードの読み方は,
  d rwx r-x r-x
  ^ ^^^ ^^^ ^^^
  |  |   |   |
  |  |   |   アザーズパーミッション
  |  |   |
  |  |   グループパーミッション
  |  |
  |  ユーザーパーミッション
  |
  ファイルの型(type)

となります. 各箇所で取りうる文字は,
  - --- --- ---
  d rwx rwx rwx
  l   s   s   t
  s   S   S
  b
  c
  P

です.

左端の文字とファイルの型は, 次のように対応づけられています.

- 通常のファイル
d ディレクトリ
l シンボリックリンク
s ソケット
b ブロックデバイス
c キャラクタデバイス
P 名前つきパイプ

また, 利用権限は以下の通りです.

- その権限が出ていない
r 読み込み許可
w 書き込み許可
x 実行許可
s s ビットが立っていて, かつ実行許可
S s ビットが立っていて, かつ実行不可
t スティッキー(sticky)

s ビットについては後述します (スティッキー(sticky)については[付録2]参照).

上の出力結果において, ドット(.) で始まるファイルが存在したと思います. これはユーザの環境を設定する為のファイルで「ドットファイル」と呼ばれます. オプションをつけずに ls コマンドを打っても表示されません. その為隠しファイルと呼ばれることもあります. この実習では特に設定を変えることはありませんので, 詳細については触れないことにします.


※ファイルの所有者, ファイルの属するグループを変更するには chown, chgrp といったコマンドを使用します.

利用権限の設定(ファイルモードの設定)

ファイルの利用権限を設定するには chmod コマンドを用います. 基本的な使い方は次の通りです(詳しくは man chmod).

$ chmod <mode> file1 [file2 ...]

<mode> の部分には 0 から 7 までの数字を 3 桁並べたものが入ります. 左の桁から順にファイルの所有者, ファイルの所属グループ, その他のユーザーに対する利用権限を示します. 各々の読みだし, 書き込み, 実行権限は 4, 2, 1 の数字で表され, 上の <mode> にはこの数字の和が代入されます.

許可 記号 数字
読込 r 4
書込 w 2
実行 x 1

例えば, モードを -rw-rw-r-- と変えたい場合,

-rw-rw-r--	
 42 42 4
 |  |  |
 6  6  4  <mode>
となるので,
$ chmod 664 file
とすれば変更できます.

上では <mode> を数字で与えましたが, 記号で与えることもできます. <mode> の数字列の代わりに,

対象 操作 許可
[ugao] [+-=] [rwxst]

という形式を "," で区切って並べます.

対象と操作の文字は以下の意味を表します.


※許可の所はファイルモードと同じです.
対象   操作
u :所有者
g :グループ
o :その他のユーザ
a :全員(ugo と同じ)
 
+ :許可を与える
- :許可を取り消す
= :許可を設定する

この場合, 先の例と同じ設定にするには次のようにします.

$ chmod u=rw,g=rw,o=r file

グループという概念について

ここまでグループという語が何度か出てきました. グループとは複数のユーザを管理する為の単位で, 共同作業する際に便利です. 例えば, 研究室において複数の人間がファイルを共通で管理したい場合に グループという概念は非常に重要なものとなるでしょう.

ここではグループの作成, ユーザのグループへの追加の方法を学び, グループの有用性を体感してみましょう.

グループを新たに作成する為には, addgroup というコマンドを用います. 但し, アカウントを新たに作成するコマンド adduser 同様, root でなければ addgroup コマンドを実行することは出来ません. VTA の人に addgroup コマンドを実行してもらいましょう (VTA の人は別ターミナルで su を使って一般ユーザになった後, sudo を実行して root になって下さい).

# addgroup inex

これで inex というグループが作成された筈です. 前回のレクチャーで少し触れましたが, グループの基本情報は /etc/group に記述されています. このファイルは一般ユーザでも閲覧できますので, 受講生の皆さんは /etc/group の中身を見てみましょう.

$ less /etc/group

/etc/group の最下行に以下のような記述があると思います. この行は addgroup を実行したことによって加わったものです.

inex:x:1005:

この時点で inex グループに所属するユーザはいません. 再び root である VTA の人の力を借りて, 皆さんと VTA の人をグループに追加してもらいましょう. グループの追加は adduser コマンドで行うことが出来ます.

# adduser foo inex

これで foo というユーザが inex グループに追加された筈です. /etc/group を見ると, 先程の行の一番右のコロン以下にユーザ名が記述されているのが 確認できると思います. 同様の手順で VTA のアカウントもグループに追加しましょう (これ以降 VTA の人のアカウント名が vta であるとして話を進めます).

inex:x:1005:foo, vta

もう 1 つ VTA の人に作業をしてもらいましょう. /home 以下に作業ディレクトリ work を作ります. 更に所有者・所有グループを変更するコマンド chown を用いて, work ディレクトリの所有者を foo, 所有グループを inex とします. またグループの書き込みを許可します.

# cd /home
# mkdir work
# chown foo:inex work
# chmod g+w work

受講生の皆さんは ls -l コマンドを使って work ディレクトリの所有者・所有グループを確認してみてください.

$ ls -l /home/
drwxrwxr-x 2 foo inex      4096 Apr 28 02:28 work

ここで work ディレクトリ内にファイルを作成してみましょう. めでたくファイルが作成出来たと思います.

$ cd /home/work/
$ echo "test" > test.txt
$ ls -l
-rw-r--r-- 1 foo  foo  7 2011-04-28 03:24 test.txt

ところが, 実はこれだとめでたくないのです. vta は inex グループに入っているのですが, この状態では vta が test.txt を編集することは出来ません. つまりこれでは inex グループに入っている foo, vta の 2 人がファイルを編集できる状態にはなっていないのです.

そこで次のコマンドを実行してみましょう.

$ sg inex
$ echo "test" > test2.txt
$ ls -l
-rw-r--r-- 1 foo  foo   7 2011-04-28 03:24 test.txt
-rw-r--r-- 1 foo  inex  7 2011-04-28 03:29 test2.txt

test2.txt の所有グループが inex になりましたね. sg コマンドは, 指定したグループでコマンドを実行する為のコマンドです. この場合 inex グループとして test2.txt を作成したので, 所有グループが inex となっています.

これで一見めでたくなったかに思われるのですが, 当初の目標である 「foo, vta の 2 人がファイルを直接編集できる状態」にはなっていません.


発展問題: text2.txt を foo, vta が直接編集できるようにするには, vta はどうすれば良いか(但し root 権限は使わないものとする).

s ビット

s ビットとは, あるファイルの実行者を「成り変わる」機能のことを言います. s ビットには, SUID ビットと SGID ビットの二種類があります.

具体例で見て行きましょう. SUID の例として /usr/bin/passwd を見てみます.

第二回目の実習で, passwd コマンドが出てきました. この passwd は /usr/bin/ ディレクトリに存在します (前回登場した /etc/passwd とは別物であることに注意しましょう). passwd コマンドを実行してパスワードを変更すると, /etc/shadow が書き変わるのでしたね. そこで, /etc/shadow のパーミッションを見てみると,

$ ls -l /etc/shadow
-rw-r-----    1 root     root        22485 Apr 28 03:52 /etc/shadow

ですから, このファイルの書き込みができるのは, このファイルの持ち主, すなわち root だけです. しかし, 誰もがパスワードを変更したい(/etc/shadow が書き変わって欲しい) と思っています. どうやって /etc/shadow を書き変えることができるのでしょうか?

そこで /usr/bin/passwd のパーミッションを見てみます. すると,

$ ls -l /usr/bin/passwd
-rwsr-xr-x    1 root     root        24680 Apr  1 02:50 /usr/bin/passwd
となっています.

左から 4 番目に s という文字が書かれています. これが SUID ビットで, このファイルが実行されると, プログラムの持ち主がこのファイルを実行したものと解釈されることを表します. つまり, passwd コマンドを実行すると, root が実行したものと解釈される のですから, /etc/shadow を書き換えることができるという訳です.

root が所有者であるファイルやディレクトリに対して, SUID ビットを設定する場合は注意が必要です. 仮の話ですが(実際はそうなっていませんので安心してください), 例えば passwd にバグ(不具合)が含まれていて, 他のユーザのパスワードを変えることができるようになってしまっていたとしたら, SUID ビットを設定することによって大惨事が起こってしまうことになるでしょう (誰かに他のユーザや root のパスワードを変えられたら, 場合によっては恐ろしいことになるわけです).

SGID は上のグループ版です. 似たようなものなので説明は割愛します.

・リンク

リンクとは, あるファイルやディレクトリを, 別のファイルやディレクトリに関連付ける仕組みをいいます.

リンクには,

の2種類があります.

ハードリンク

先に ls コマンドを用いた説明で, その実行結果の左から2番目に表示される数字は, リンク数を表すと述べました.

$ ls -l sample.txt
-rw-r--r--   1 inex     epnetfan      363 Jun 20 12:11 sample.txt

これは正しくは「ハードリンク」の数を表しています. ハードリンクの数は, 簡単に言うとファイルの「名前」の数を表しています.

人間は文字列(上の場合 'sample.txt')でファイルを識別しますが, システムはファイルを「番号」として管理しています. UNIX では, この番号を「i-ノード」と呼びます. ファイルと i-ノード番号は1対1に対応(リンク)しています.


※以下, 小文字の箇所は, 最初は読み飛ばして良い.

i-ノードという概念は, そもそも UNIX のカーネルが, それぞれのパーティションに, 装置番号(device number)を割り当て, 「ディスク」ではなく「ファイルシステム」 という論理的なレベルで処理を行うことに由来しています. ファイルシステムは, 論理的なブロックの集まりから構成され, 単位となるブロックの大きさはシステムによって異なります.

ファイルシステムは, 次のような4つの部分に分けられます.

  • ブートブロック:ファイルシステムの先頭には, マシンを立ち上げる bootstrap コードが格納されます. システムを立ち上げるには, 一つのブートブロックがあれば十分なのですが, 全てのファイルシステムが, ブートブロックを持っています.
  • スーパーブロック:ここには, ファイルシステムの大きさや, どこに空き領域があるかといった、ファイルシステム自身の管理情報が格納されます.
  • i-ノードリスト:スーパーブロックに続くのは iノードのリストです. i-ノード自身が持つ情報は次に紹介します.
  • データブロック:この部分には, ファイルシステムの実体をなすファイルのデータやディレクトリの情報が格納されます.

i-ノードには, 次のような情報が含まれています. ここで注意して欲しいことは, i-ノードにはファイル名は含まれていないということです.

  • ファイルの所有者
  • ファイルの型
    1. 通常のファイル
    2. ディレクトリ
    3. スペシャルデバイスファイル(キャラクター, ブロック)
    4. FIFO
  • ファイルアクセスのパーミッション
  • タイムスタンプ
    1. 最終変更時間
    2. 最終アクセス時間
    3. 最終属性変更時間
  • リンク数
  • ファイルのデータのディスク上のアドレスの情報
    ※ユーザーは, ファイルをバイトストリームとして扱いますが, カーネルは, データをディスク上の不連続なブロックに格納しています. i-ノードは, その表を持っています.
  • ファイルの大きさ

ls -i とするとファイルの i-ノード番号を実際に見ることができます.

$ ls -i sample.txt
  31657 sample.txt

ハードリンクの数は, 実はそのファイルの対応している i-ノード番号を 参照しているファイルの数を表しています.

したがって同じ i-ノード番号をもつ別名のファイルを作ること, 即ちファイルに複数の名前をつけることができます. これは "ln" コマンドで実行できます.

touch コマンドで空のファイル file1 を作り試してみましょう. 通常ファイルのリンク数は1です.

$ touch file1
$ ls -l file1
-rw-r--r--   1 inex     epnetfan   0 Jun 27 02:39 file1

ここで
$ ln file1 file2
とすると file1 に新しい名前 file2 を加える(リンクを張る)ことができます.
$ ls -l file1 file2
-rw-r--r--   2 inex     epnetfan   0 Jun 27 02:39 file1
-rw-r--r--   2 inex     epnetfan   0 Jun 27 02:39 file2

リンク数が2に増えています. 一方ディレクトリのリンク数は必ず2以上になります. リンクを消すには rm コマンドを使います.

シンボリックリンク

上の ln コマンドにオプション -s をつけて実行してみます. これは「シンボリックリンク」と呼ばれ, 簡単にいうとファイルの「別名」をつけるようなものです. 類似のものに, Windows では「ショートカット」, Mac では「エイリアス」があります.

$ ln -s file1 file3
$ ls -l file1 file3
-rw-r--r--   2 inex     epnetfan   0 Jun 27 02:39 file1
lrwxrwxrwx   1 inex     epnetfan   5 Jun 27 02:45 file3 -> file1

ハードリンクの場合は i-ノードを直接参照しているのに対し, シンボリックリンクは「ファイル名」を参照しています. 従って、上の例でも file1 のリンク数も増えませんし, file3 のリンク数も1のままです.

シンボリックリンクの特徴をみるため, 次のようにコマンドを実行してみましょう.

$ rm file1
$ cat file3
cat: file3: No such file or directory

するとエラーが返されます. しかし,
$ ls file3
file3

となり file3 そのものは存在します.

これはシンボリックリンクでは「ファイル名」を参照しているためです. 参照先のファイル名が消去されてしまうと, 参照していたファイルの i-ノードを見ることができなくなり, 上の例では file3 を表示しようとするとエラーが返るのです.

ハードリンクとは異なり, ディレクトリに対するシンボリックリンクは可能です. シンボリックリンクを消すにはやはり rm コマンドを使います.

・その他の解説

スティッキー(sticky)ビット

スティッキービットとは, ファイルまたはディレクトリの所有者だけが目的のファイルの削除や名前の変更を行えるようにする機能のことです.

s ビットの時と同様に具体例で見て行きましょう. ルートディレクトリ( / )の下には tmp というディレクトリがあります. このディレクトリのパーミッションを見ると,

$ ls -l /
drwxrwxrwt   6 root     root    1024 Jul  1 12:16 tmp

となっています.

これによるとこのディレクトリは誰でも読み書きができるようになって いますが, 「アザーズ」の実行許可のところに t と書かれています.

これがスティッキービットで, それによって, このディレクトリの中にあるファイルの消去や名前の変更は, そのファイルの所有者だけが行えるようになるということになります.

デバイスファイル

ls -l /dev としてみると以下のような出力が得られます.

$ ls -l /dev/
total 50
-rwxr-xr-x   1 root     root   14373 Nov 30  1996 MAKEDEV*
-rwxr-xr-x   1 root     root   28676 Nov 30  1996 MAKEDEV-C*
-rw-r--r--   1 root     root    1035 Nov 30  1996 README.MAKEDEV
-rw-r--r--   1 root     root    1434 Nov 30  1996 README.MAKEDEV-C
lrwxrwxrwx   1 root     root       4 Jan 15 21:46 X0R -> null
crw-r--r--   1 root     root 10, 134 Jun  8  1996 apm_bios
crw-------   1 root     root 16,   1 Feb 19  1994 arp
crw-rw-rw-   1 root     sys  10,   3 Jul 18  1994 atibm
crw-rw-rw-   1 root     sys  14,   4 Jul 19  1994 audio
crw-rw-rw-   1 root     sys  14,  20 Jul 19  1994 audio1
brw-r-----   1 root     disk 29,   0 Feb 16  1995 aztcd
crw-r--r--   1 root     root 10, 128 May 25  1996 beep
.
.
.
crw-r-----   1 root     disk 27,  25 Dec  8  1995 zqft1
crw-r-----   1 root     disk 27,  26 Dec  8  1995 zqft2
crw-r-----   1 root     disk 27,  27 Dec  8  1995 zqft3

ファイルモードを見ると, 一番左が見慣れない c や b になっています. このようなファイルは通常のファイルではありません.

UNIX では基本的にあらゆる物を抽象化して「ファイル」として扱います. たとえばマウス(/dev/mouse) や画面等もファイルに抽象化して取り扱ってしまいます.

このようなファイルは「デバイスファイル(device file)」と呼ばれます. デバイスファイルには, c で表されるキャラクタデバイスと, b で表されるブロックデバイスがあります.

ソケット

ソケットはプロセス間通信の終端点です. プロセス間通信には, パイプや TCP/IP (第 5 回) などいろいろな方法がありますが, その中に数えられる UNIX ドメインのソケット (同一コンピュータの内部で閉じたぷプロセス間通信で使うソケット) はファイルとして見えます.

代表的なソケットとしては以下の 2 つがあります.

$ ls -l /dev/{log,printer}
srw-rw-rw- 1 root root 0 2011-04-27 06:25 /dev/log
srw-rw---- 1 root lp   0 2011-04-25 06:47 /dev/printer 

ファイルタイプには s と書かれています. これがソケットを表します. /dev/printer はプリンタにつながっているソケットですが, 直接プリンタデバイスにつながっている訳ではありません. lpd (line printer daemon) が中継します. このソケットは, lpr コマンド (印刷するためのコマンド) が lpd デーモンと通信する時に使われます.

名前付きパイプ

その名のとおり, 名前がついたパイプのことです. UNIX 内のプロセス間通信を行うために用いられます. 普通のパイプの場合, 親子または兄弟のプロセス間でしか通信できないという制限がありますが, 名前つき パイプの場合, 親子兄弟関係にないプロセスとも通信できます.

$ mknod pipe p
$ ls -l pipe
prw-r--r-- 1 foo foo  0 2011-04-28 22:21 pipe 

ファイルタイプに p と書かれていることが, 名前つきパイプであることを表しています. 実際に名前つきパイプを作ってみましょう.
もう一つ kterm を開きます.

$ kterm &

1 つ目のターミナルで cal コマンドを用いてを pipe に書き込みます.

$ cal > pipe

2 つ目のターミナルでカレンダー中の 2010 を抜き出します.

$ grep 2011 pipe
    4月 2011

このように, 名前つきパイプを使うことで「cal | grep 2011」を分けて使うことができます.




次へ >>

最終更新日: 2012/04/19(高橋康人) Copyright © 2012 inex