2000 年度「計算機基礎論3B」 ディレクトリとファイル

ディスクの中にはたくさんのディレクトリがあり、 それぞれにファイルが置かれています。

ディレクトリは次の図のようにツリー(tree)状につながっています。 この構造のことを「階層ディレクトリ構造」ともいいます。

       +- etc               +- iwase
       |                    |
    / -+        +- kakuma  -+            +- cf1920  -- nsmail
       |        |           |            |
       +- home -+           +- iwase1   -+
       |        |           :            |
       :        |           :            +- eb12g01 -- nsmail
       :        |                        |
                |                        +- eb12g02 -- nsmail
                |                        :
                |                        :
                |                        +- eb12g48 -- nsmail
                |
                |
                +- kakuma2 -+- iwase    -+- iwase
                |           |
                :           :

一番左の「/」は「ルート(root)」 あるいは「ルートディレクトリ」と呼ばれ、 根にあたります。 なぜかルートの方向を上、 その反対方向を下という習慣になっているので、 / が一番上、そのすぐ下に etc や home があり、 home の下には kakuma, kakuma2 がある、 といった具合になります。

ルート以外のディレクトリから見ると、 すぐ上のディレクトリ (以下「親ディレクトリ」という) は必ず一つだけ存在しています。 すぐ下のディレクトリは存在しないこともあるし、 ひとつだけ存在することも、それ以上存在することもあります。 このことをツリー状と表現しているのです。

ルート以外のディレクトリを「サブディレクトリ(subdirectory)」 と呼ぶことがあります。

任意のディレクトリに対し、 そのすぐ下のディレクトリの名前は互いに異なっていなければなりません。 それ以外のところに同じ名前が現われることは構いません。 上の図の中だけでも3つの iwase が現われています。

WS を使っているときには常にどこか一つのディレクトリが 「カレントディレクトリ(current directory)」 と呼ばれるものになっています。

上の図で eb12g01, eb12g02, ..., eb12g48 と書かれたところのどこかに、 みなさんのログイン名と同じ名前のディレクトリがあります。 そこが各自の「ホームディレクトリ(home directory)」と呼ばれ、 ログインした直後にはそこがカレントディレクトリになります。

ログイン直後に ls を実行した際に見えたディレクトリはみなさんのホームディレクトリのすぐ下にあるディレクトリであり、 見えたファイルはホームディレクトリに置かれているファイルでした。

ディレクトリを指定する文字列を「パス(path)名」といいます。 それには「絶対パス名」と「相対パス名」の二種類があります。

※ 上にも書いたように、 同じディレクトリ名をもつディレクトリが複数あることがあるので、 単純に上の図に書かれた名前だけではディレクトリを特定できないことに注意。

絶対パス名は「/」で始まり、 ルートから順にそのディレクトリ名をたどって降りていった先のディレクトリを表わします。 /home は図で home と書かれた(図の中では唯一の)ディレクトリ、 /home/kakuma2 は図で kakuma2 と書かれた(図の中では唯一の)ディレクトリ、となります。 /home/kakuma2/iwase, /home/kakuma2/iwase/iwase が上の図のどのディレクトリを表わすかはわかりますよね?

※ このあたりで、上のツリーの絵とだいぶ離れてきて見にくいかもしれません。ごめんなさい。

相対パス名は「/」で始まらないパス名で、 カレントディレクトリから順にそのディレクトリ名をたどっていった先のディレクトリを表わします。 例えばカレントディレクトリが /home/kakuma2 のとき、 iwase/iwase は /home/kakuma2/iwase/iwase を指します。

※ パス名を口に出していうときは「/」を「スラ」という人が多いようだ。

そのほかに、パス名に使われる特殊な記号があります。

    .         カレントディレクトリ[ピリオド一つ]
    ..        親ディレクトリ[ピリオド二つ]
    ~         自分のホームディレクトリ[「へ」をシフトして入力]
    ~iwase    ユーザ iwase のホームディレクトリ

例えばみなさんのホームディレクトリがカレントディレクトリのとき、 「..」は /home/kakuma/iwase1 を表わし、 「../cf1920」は /home/kakuma/iwase1/cf1920 を表わします。

ファイルにも「パス名」があります。 ファイルは必ずどこかのディレクトリに置かれています。 例えば tx.scr という名前のファイルがディレクトリ /home/kakuma/iwase1/cf1920 に置かれていたら、 そのファイルの「絶対パス指定」は /home/kakuma/iwase1/cf1920/tx.scr となります。 もしもカレントディレクトリが /home/kakuma ならば iwase1/cf1920/tx.scr と 「相対パス指定」しても同じファイルを指します。

もう少し例をあげると、 「~/tx.scr」は自分のホームディレクトリにある tx.scr という名前のファイルを、 「~iwase/tx302」はユーザ iwase のホームディレクトリにある tx302 という名前のディレクトリを表わします。

なお、 名前だけをみてそれがファイルなのかディレクトリなのかを判断する方法はありません。 (上にあげた「..」などは除く。)

※ 上の説明では、 ファイルはディレクトリ「に」置かれているとしたが、 ディレクトリの「下に」置かれていると考えてもよい。
   +-- cf7175 --+   +-- nsmail --+
   | tx.scr     |   |            |
---+ tx.usr     +---+            |
   |            |   |            |
   +------------+   +------------+
と考えるか、

----- cf7175 -----+---- nsmail --- ...
                  |
                  +---- tx.scr
                  |
                  +---- tx.usr
と考えるかの違い。

unix のファイル・ディレクトリ操作コマンド

ls -al

「ls -al」(オプションはエイ、エル)とすると、 単に「ls」としたときよりもたくさんの情報が表示されます。 ファイル名・ディレクトリ名以外の情報も表示されるし、 表示されるファイル・ディレクトリの数も多くなっています。 カレントディレクトリにあるファイル、 カレントディレクトリのすぐ下のあるディレクトリはここに表示されているもので全てです。

※ 以下の出力例は 1999 年度のもの。

    ws47{cf7175}50% ls -al
    合計 50
    drwxr-xr-x   7 cf7175   iwase        512 10月 12日  17:06 ./
    drwxr-xr-x  51 root     other       1024  9月 28日  02:15 ../
    -rw-------   1 cf7175   iwase        735 10月  7日  18:33 .Xauthority
    -rw-r--r--   1 cf7175   iwase       2790  9月 28日  02:14 .cshrc
    -rw-r--r--   1 cf7175   iwase        971 10月  7日  18:55 .desksetdefaults
    -rw-r--r--   1 cf7175   iwase       4712  9月 28日  02:14 .emacs
    drwx------   3 cf7175   iwase        512 10月  7日  18:47 .fm/
    -rw-r--r--   1 cf7175   iwase        575  9月 28日  02:14 .login
    -rw-r--r--   1 cf7175   iwase       1491  9月 28日  02:14 .mailrc
    drwx------   5 cf7175   iwase        512 10月  7日  18:32 .netscape/
    -rwxr-xr-x   1 cf7175   iwase       1090  9月 28日  02:14 .openwin-init*
    -rw-r--r--   1 cf7175   iwase        306  9月 28日  02:14 .rhosts
    drwxr-xr-x   2 cf7175   iwase        512 10月  7日  19:27 .wastebasket/
    drwx------   2 cf7175   iwase        512 10月 11日  17:20 mail/
    drwx------   2 cf7175   iwase        512 10月  7日  18:32 nsmail/              
    -r--r--r--   1 cf7175   iwase       1016  9月 30日  18:24 tx.scr
    -r--r--r--   1 cf7175   iwase        160 10月 11日  17:03 tx.usr

         ↑          ↑       ↑         ↑      ↑       ↑    ↑
  パーミッション   所有者  グループ  バイト数   日付     時刻 ディレクトリ名・ファイル名
なお、カレントディレクトリのすぐ下にあるディレクトリのほかに、 上で説明した「.」「..」も表示されることになっています。

「.」で始まる名前をもつファイル・ディレクトリは ls では表示されません。 これらは、種々の設定用ファイルがほとんどです。 ユーザは、特に理由がなければこのような名前をもつファイル・ ディレクトリを作るべきではありません。 また、よくわからずにこのような名前をもつファイル・ ディレクトリを削除したり改名したり内容を変更したりしてはいけません。 (読むのは構いません。)

「パーミッション(permission)」というのは、 ファイルやディレクトリに対する読み書きの許可のことです。

最初の1文字(「d」や「-」)は抜かすことにして、次の9文字は

  最初の3つの rwx ……所有者 cf7175 自身に対して
   次の3つの rwx ……グループ iwase のメンバーに対して
  最後の3つの rwx ……すべての人に対して
のパーミッションを示しています。rwx は
  r ... 読み取り許可
  w ... 書き込み許可
  x ... 実行許可
の意味です。 例えばファイルが「-rw-r--r--」だった場合、 所有者は読み書き可、グループのメンバーと他人は読み取りのみ可、となります。 ディレクトリの場合は少々違った意味になります。 いまの段階では、 rwx または r-x のディレクトリはそこをカレントディレクトリにできる、 「---」だったらできない、と理解しておきましょう。

ただし、「スーパーユーザ(superuser)」と呼ばれる管理者は、 パーミッションに関係なくすべてのファイル・ディレクトリに対しなんでもすることができます。 マスターキーを持っている大家さんのようなものです。 スーパーユーザのログイン名は root です。 私(岩瀬)は実習用 WS のスーパーユーザではありません。

「所有者」はファイル・ディレクトリの所有者です。 WS のディスクは全員で一つのものを使っていますが、 個々のファイル・ディレクトリは所有者がはっきり決まっています。 「グループ」の機能は一般ユーザの間ではあまり有効に使われていないようなので省略しますが、 みなさんは私と同じグループに属しています。

「バイト(byte)数」はそのファイルのバイト数です。 ファイルの中味が文書の場合、 「abc123」のような半角文字は一文字1バイト、 「あいうえお」のような全角文字は一文字2バイトとしてカウントされます。

「日付」「時刻」はそのファイル・ディレクトリを最後に修正した日時を表わします。 6カ月以上前のファイルの場合、時刻の代わりに年が出ます。

「.open-win.init*」のように「*」がついているのは実行ファイルです。 プログラムとして実行できるファイル、というぐらいの意味。 この「*」はファイル名には含まれません。

ファイルが多すぎて画面が流れるときは「ls -al | more」としてください。 「-- 継続 --」が出て止まったらスペースで次の画面、「q」で中止です。

※ 試してみたかったらカレントディレクトリを /etc に移して実験するとよいでしょう。 cd のところを読んだあとでやってみましょう。

「ls tx.scr」「ls -al tx.scr」とすればそのファイルについてだけ表示させることができます。

※ 諸君のアカウントにはしかけがしてあり、 単に「ls」としても「ls -F」が実行されるようになっている。 「ls -al」は「ls -alF」なのである。 また、「ls -al」の代わりに「ls -la」としてもよい。 なお、単なる「ls」をめったに使わないなら、 「ls」とだけ打って「ls -alF」が実行されるよう自分で設定することもできる。 それはまたそのうち。

pwd

カレントディレクトリの絶対パス名を表示させるコマンドです。

    ws47{cf7175}23% pwd
    /home/kakuma/iwase/cf7175

cd

パス名を引数にとり、 それで指定されるディレクトリをカレントディレクトリにするコマンドです。 引数がないと、ホームディレクトリがカレントディレクトリになります。

  「cd /home/kakuma」 絶対パス
  「cd mail」         相対パス
  「cd ..」           親ディレクトリ
  「cd ~」            ホームディレクトリ
  「cd ~iwase」       iwase のホームディレクトリ

  「cd」              ホームディレクトリ

※ もうひとつ、例外的な動作がある。 引数が相対パス名でありかつそのディレクトリが存在しないと、 ~/引数 に移動するのだ。

    ws47{cf7175}29% cd mail
    ~/mail 

パーミッションが「---」のディレクトリ、 およびそれより下のディレクトリをカレントディレクトリにすることはできません。

いろいろなディレクトリを動き回ってみてください。

cat

cat の引数にはファイル名だけでなくパス名も使えます。 例えば「cat ~iwase/tx.usr」とすればファイル ~iwase/tx.usr の内容が画面に出力されます。

※ 実行ファイルの中には cat すると意味不明な文字があとからあとから出てきてどうしようもなくなるものもあるから要注意。 さしあたっては、cat しないほうがいいかも知れない。 ディレクトリも cat しないこと。してもいいことは何もない。

読み出しパーミッションのないファイルは cat できません。 例えば iwase のホームディレクトリにあるファイルで試してみてください。

chmod

第一引数に数を、第二引数にパス名をとり、 第二引数で指定されたファイル・ディレクトリのパーミッションを、 第一引数で指定されたものに変更します。 例えば「chmod 600 tegami」は tegami のパーミッションを 600 に、 「chmod 644 /home/kakuma/iwase/cf7175/tegami」は /home/kakuma/iwase/cf7175/tegami のパーミッションを 644 に変更します。

パーミッションを数で表現するには、左から順に

       r ... 400
       w ... 200
       x ... 100
       r ...  40
       w ...  20
       x ...  10
       r ...   4
       w ...   2
       x ...   1
と対応させ、「-」でない部分だけ足し合わせます。 くり上がりはないから簡単です。 rw-r--r-- なら「644」になります。

よく見かけるパーミッションの例をあげておきます。 これ以外のものにセットすることはほとんどありません。

ファイルの場合:

  644 (rw-r--r--) ... 所有者は読み書き可。他の人は読むだけ。普通のファイル。
  600 (rw-------) ... 所有者だけ読み書き可。秘密のファイル。
  755 (rwxr-xr-x) ... 所有者は読み書き実行可。他の人は読むと実行だけ。実行ファイル。

ディレクトリの場合:

  755 (rwxr-xr-x) ... 誰でもはいれる。所有者は書き込める。普通のディレクトリ。
  700 (rwx------) ... 所有者だけがはいれて書き込める。秘密のディレクトリ。

※ たいていの場合、グループに対するパーミッションと他人に対するパーミッションは同じにする。 つまり、2ケタ目と3ケタ目は同じ数字になる。

※ 自分自身も自分と同じグループに属しているので、 厳密にはグループに対するパーミッションというのは 「自分以外のグループメンバーに対してのパーミッション」となる。 同様に他人は「グループメンバー以外の他人」の意。

友だちと組んで、パーミッション変更をしては「見えるか?」などと実験をしてみてください。 (以下の mkdir なども参照のこと。)

まだみなさんは“秘密”のものを WS に置いてはいないと思いますが、 そういったものは他人に見えないようにパーミッションを設定しておくべきです。 別の言い方をすれば、見えるようなパーミッションでファイルが置いてあれば 「読んで構わない」という意思表示だととられます。

mkdir

「mkdir dirname」で、 カレントディレクトリのすぐ下に dirname という名前のディレクトリを新しく作ります。 できたディレクトリのパーミッションは rwxr-xr-x になります。 カレントディレクトリに書き込みパーミッションがないと失敗します。 (ここで dirname はディレクトリ名のつもり。)

rmdir

「rmdir dirname」で、 カレントディレクトリのすぐ下のディレクトリ dirname を削除します。

もしもディレクトリが空でないと (i.e. その下にディレクトリがあったりそこにファイルが置いてあったりすると) メッセージが出て削除は行なわれません。

※ dirname の書き込みパーミッションはこのコマンドの成功・失敗と関係がない。 関係あるのはカレントディレクトリの書き込みパーミッションらしい。

cp, mv, rm

これらは本編でも出てきましたが、 そこで「ファイル名」と説明したところにパス名が使える場合があります。

※ 以下では引数(argument)ということで arg と書いてみました。 偏角じゃないぞ。

「cp arg1 arg2」の arg1 にはファイルを指すパス名が使えます。

※ arg2 にもパス名が使える場合があるけど、ここでは省略。

「mv arg1 arg2」の arg1 にはパス名が使えます。 arg1 がファイルを指していればファイルの、 ディレクトリを指していればディレクトリの改名が行われます。 mv はファイルの移動にも使えます。 第二引数がディレクトリを指すパス名である場合、 第一引数の指定するファイル・ディレクトリを第二引数の指定するディレクトリに移動します。

「rm arg1」の arg1 にはパス名が使えます。

コピーしたファイルのパーミッションは rw-r--r-- になります。 mv はパーミッションを変えません。

コピー先のディレクトリ(ここで説明した方法ではカレントディレクトリに限る) に書き込みパーミッションがないとコピーできないなど、 パーミッションによってこれらのコマンドは成功したり失敗したりします。 chmod のところで例にあげたようなパーミッションの設定をした場合、 「他人のファイルやディレクトリは見ることはできても変更はできない」 という常識的な結果になります。

more

more は cat と似ていますが、 ファイルの内容を一画面ずつ見ることができます。 「-- 継続 --」が出て止まったらスペースで次の画面、 「q」で中止です。

※ タイピング練習を一生懸命やった人は more ~/tx.scr で実験できるはず。

「パス名」「ファイル名」「ディレクトリ名」という用語に関する注意

ここまでの「パス名」「ファイル名」という用語は JIS X 3030 (1994) 「移植可能なオペレーティングシステムのインタフェース (POSIX) ―第1部 応用プログラム向けのインタフェース (API)[プログラム言語C]」 という規格内の定義に基づいて使ってきました。

しかし、実際には「ファイルを指定するパス名」の意味で「ファイル名」ということが多いようです。 つまり、今までの言葉づかいだと /etc/passwd はファイルを指すパス名であってもファイル名ではなかったわけですが、 これをファイル名ということも多いのです。 同様に、「ディレクトリを指定するパス名」を「ディレクトリ名」と呼ぶことがあります。 今後はこのような言い方も使うことにします。

なお、本当に厳密にその規格に従うなら、 「ディレクトリ名」という用語はありません。 ディレクトリは特殊なファイルと考え、 上で「ディレクトリ名」と言っていたものもファイル名に含まれるのです。


岩瀬順一 <iwase@kappa.s.kanazawa-u.ac.jp>