ファイルシステムとディレクトリ操作

ファイルシステムとは?

今後,プログラム作成やレポート作成などで数多くのファイルを作ってゆくが, それらのファイルを目的別に整理・分類する仕組みとしてディレクトリの概念がある(WindowsやMac OS Xではフォルダと呼ばれる考え方に相当する). このディレクトリをコンピュータ内部で実現する仕組みをファイルシステムと呼ぶ. ファイルシステムは利用するOSによって様々な種類のものがあり,内部的な構造や実現方法がそれぞれ異なってはいるが, 利用者から見れば基本的な考え方は概ね同じである.Mac OS Xがサポートする(利用できる)ファイルシステムにはHFS+などがあり, Windowsで利用できるものには,FAT, FAT32, NTFSといった種類がある(尚,Mac OS XでもFATやFAT32を利用できる.市販のUSBメモリがWindowsだけでなくMacでも使えるのはそのため).

授業での説明上,ディレクトリと呼んだりフォルダと呼んだりと場合によって適当に使い分けるが,本質的には同じ事を指している.感覚的にはターミナル上でコマンド操作を意識している時にはディレクトリ,FinderなどGUI操作を意識している時にはフォルダと呼ぶ事が多いと思う.

ディレクトリとその必要性

まず日常生活で考えてみよう.沢山のモノが一ヶ所にある例として,例えばユニクロ店舗やデパートなどの商品販売の場がある.ユニクロでは,店舗内を男性向け・女性向け・キッズ向けといった具合にコーナー分けした上で,各コーナーでTシャツ・ジーンズ・ポロシャツといったように各商品を種別毎に分類して見やすく展示している.また,デパートでは扱う商品は数十万点にも及ぶので建物全体を「紳士用品」「レディース用品」「食料品」など各フロア毎に扱う商品を大まかに分け,更に各フロア毎に「スーツ」「スポーツ用品」「おもちゃ」といったように売り場を分けて商品を配置している.

もし,こういう整理分類した商品配置が無く,鯛の刺し身の隣に靴下が並べてあり,その隣にテニスラケットが売られているという具合に数十万点の商品が何の脈絡もなくデタラメに並べられていたら,お客様は自分の欲しい商品を見つけることが出来るだろうか?

このよう沢山のモノを取り扱う場合,まず大まかに分類しておいてから,さらに細かく分類して整理することは,人間にとって自然で分かり易い方法である.ファイルも例外ではない.普通,UNIXで取り扱うファイルの数は非常に膨大になるので,これを適切に分類整理して取り扱う仕組みがないと,訳が分らなくなってしまう.

この状況に対処する為,UNIXでは各ファイルを分類整理して入れておく入れ物を用意している.これがディレクトリである.ちなみに,デパートの入り口に各フロアの取り扱い商品を記した「案内板」を一度は見たことがあるだろう.あれを英語でディレクトリ (Directory)と呼びのだが,これがUNIXのディレクトリの由来である.

今,手元に3つのレポート用ファイル,3つのデータ処理用ファイル,4つのプログラムファイル(C言語が2つ,Java言語が2つ)あると仮定しよう.これを各種類ごとに分類してみたのが以下の図である.

楕円はそれぞれファイルを表しており,四角で囲まれたreports, data, program, javaがそれぞれ分類を表している.このそれぞれ名前が付けられている四角がディレクトリを意味しており,幾つかのファイルを分類する入れ物となっている.

尚,一つのディレクトリに分類して配置できるファイル数に実質的な制限は無く,ディレクトリにディレクトリ(サブディレクトリ,子ディレクトリ)を配置する(入れる)ことが出来る.(上の図では,programディレクトリにjavaサブディレクトリが配置されている.)

ホームディレクトリ (Home Directory)

UNIXは一般的に複数の利用者が利用するシステムであるので,各ユーザが持っているファイルやディレクトリは,各ユーザ毎に与えられた専用ディレクトリに入れられて整理される.これを「ホームディレクトリ」と呼ぶ.

各自が作成するファイルはホームディレクトリ及びそのサブディレクトリ(ディレクトリに作成した子ディレクトリ)に自由に配置・保管できる. 尚,保管できるファイルの総容量は有限であるので,不要となったファイルはいつまでも放置せずに適当に整理・削除することが望ましい.

ディレクトリとフォルダの関係,及び,Mac OS XのFinder

さて,ここでこれまでMac OS Xの様々なソフトウエアを利用してきて,ワープロ文書や画像を「ファイル」として保存操作して,後で探したり,開いて利用したり,ゴミ箱に入れて削除するのに,Mac OS XのFinderのウィンドウを通じて行ってきた.

このFinderとは,結局のところ,Mac OS Xのディレクトリやファイルの配置状況をアイコン表示を用いてコンピュータの知識のあまりない素人でも分かりやすく表示し,また,マウス操作を使って簡単に整理したり出来るようにするソフトウエアなのであった.例えば上記の例では,csetest1というユーザのホームディレクトリにはpublic_htmlというディレクトリ,或いは,Welcome.htmlとかtest.txtというファイルが配置されている状況がアイコンを使って視覚的に表示されている.

では,一見,分かりやすいと思えるFinderの方が,色々覚えなくてはならない面倒くさそうなコマンドによるファイル操作よりも優れているのか? 或いは,Finderさえあればコマンド操作は要らないのか? 

そうではない.ファイルのちょっとした整理ならばFinderで十分だが,複雑で面倒なファイル操作を簡潔に行おうとするとコマンド操作が優位となる状況は,いくらでも起きるだろう.

要は適材適所,状況によって上手に使い分けるというのが正解である.

ディレクトリツリーとパス

各ユーザのホームディレクトリは,さらにそれらを格納するディレクトリが用意されており,そこに配置される.下の図では home となっているディレクトリがそれである.尚,どのディレクトリにユーザのホームディレクトリが配置されるのかは,利用するシステム毎に異なっている.

システム全体のディレクトリやファイルは最終的に一つのディレクトリを頂点とする形(木構造)にまとめられており,これを「ディレクトリ・ツリー (Directory Tree)」と呼ぶ.

この図の上下を逆転すると,樹木が枝葉を拡げているように見えることから「ツリー構造(木構造)」と呼ばれている.

また,この木構造の最上位ディレクトリは「 / 」と名前が付けられており,これを「rootディレクトリ」と呼ぶ.(rootとは木の根っこの意)

絶対パス

この木構造に整理された沢山のファイルやディレクトリを特定するには,どうすればよいだろう.一つの方法はrootディレクトリから辿ったディレクトリ名を並べることである.UNIXでは,ディレクトリツリー上のファイル(ディレクトリ)を特定する表現方法としてディレクトリ名を / 記号で区切って並べる表記法が使われており,これを「絶対パス (Absolute Path)」(又は,フルパス, Full Path)と呼ぶ.

例えば,/ (root)ディレクトリの下のhomeの下のg012345の下のreportの下のhomework.txtというファイルは,

/home/g012345/report/homework.txt

と表記される.

カレントディレクトリ

UNIXでファイルを整理したり複製したり削除したりなどファイル操作するのは,ターミナルからコマンド入力で行う事は既に説明した.では,この時,操作しているファイルは,このディレクトリツリーのどこかのディレクトリに配置されていることになっているのだろうか?

実は,ターミナルで作業する場合,「どこのディレクトリにて作業しているか?」言い換えると「どこのディレクトリに注目して作業しているのか?」が想定された状態で作業している.この「今,注目して作業しているディレクトリ」を「カレントディレクトリ (Current Directory)」と呼ぶ.以下の概念説明図では,カレントディレクトリをアイコンで示す.

ここでターミナルを開いてみよう.カレントディレクトリの位置を確認するには, pwd コマンドを実行する.

mkbka001(100)$ pwd
/home/oomoto

上記のような結果が表示されるだろう.これは,rootディレクトリの下にあるhomeディレクトリの下のoomotoディレクトリが,カレントディレクトリであることを表示している.各自の実行結果を見て,カレントディレクトリがディレクトリツリー上のどこに位置しているか,良く考えてみよう.

尚,システムにログインした直後,又は,ターミナルを開いた直後は,カレントディレクトリは各自のホームディレクトリにセットされている.つまり,以前のコマンド操作練習で作成したlogやlog2といったファイルは各自のホームディレクトリに配置された状態になっていた訳だ.

練習

ここで,自分のホームディレクトリのディレクトリツリー上の位置も良く確認しておこう.また,既に作成したenglish.txtやjp.txtといった名前のファイルの配置も確認しておこう.ファイル配置の確認をするには,上記のような「ディレクトリ配置図」を自分で描いてみるのが最も分かりやすいので,適当なメモ用紙(ルーズリーフなど)に,各自のホームディレクトリやenglish.txtというファイルがルートディレクトリからどのような配置になっているか,簡単な図を描いて確認してみよう.

授業中にここまでの説明を聞いている時点で,机上にメモ用紙と筆記具が出ていない者が少なからずいるはずだ.そのような者は授業に集中出来てないと言わざるをえないな.

相対パス

ファイルの削除などファイル操作を行う場合,絶対パス表現を用いて指示することが出来る.例えば,

rm /home/g0123456/report/homework.txt

といった具合である.しかし,これはあまりにタイピング量が多くて面倒過ぎると思えるだろう.

そこで,カレントディレクトリの概念をつかってもう少し簡潔に短くファイルを指示出来る表現方法が「相対パス (Relative Path)」である.

今,下記の図のようにカレントディレクトリが /home/g012345 であるとしよう.

この時,このカレントディレクトリにある report ディレクトリの下にある homework.txt ファイルは

report/homework.txt

と表現する.簡単に言えば,カレントディレクトリを出発点として目的のファイルに辿り着くまでに通るディレクトリの名前を / 記号で繋げたものである.

では,カレントディレクトリよりも上位のディレクトリはどのように指示すれば良いのだろう.それには特別の名前 .. を用いる.

例えば,

という具合に表現できる.上記の図中の各ディレクトリやファイルの相対パス名を良く考えてみよう.

尚,絶対パスと相対パスの区別は,先頭の文字が / 記号で始まるかそうでないかで区別される.

相対パス表現に用いる特別の名前

相対パス表現において特別の意味を持っている幾つかの名前(記号)がある.

  1. . (ピリオド): カレントディレクトリを表す.
  2. .. (ピリオド2個): カレントディレクトリの直上(一つ上)のディレクトリを表す.
  3. ˜(チルダ記号): 各自のホームディレクトリを表す.例:˜/sample/english.txt
  4. ˜ユーザ名 : ユーザ名で示されるユーザのホームディレクトリを表す.例:˜g012345/sample/english.txt

ディレクトリ階層を考慮したファイル操作

各ディレクトリは階層構造となり,ファイルはこれらのディレクトリに整理されて配置されるから,厳密にはファイル操作する時にこの階層を意識しながら行う必要がある.ディレクトリ階層を考慮したファイル操作は以下のようになる.

ファイル一覧の表示 (list)

ファイル一覧を表示するのはlsコマンドである.

sl コマンドじゃないぞ.間違ってslコマンドを実行すると,「ちょっと楽しい何か」が起きる(^^;

引数を与えずに実行すると

ls

カレントディレクトリにあるファイルとディレクトリの名前一覧を表示する.

lsコマンドの引数にディレクトリ名を指示すると,そのディレクトリに配置されているファイル一覧を表示する.例えば,カレントディレクトリにあるprogramディレクトリに配置されたファイルの一覧を表示するには次のように実行する.

ls program

また,lsコマンドには幾つものオプションがある.

ファイル一覧の詳細表示

ls -l

-lオプションを付けて実行すると,単にファイル一覧を表示するのではなく,各ファイルに関する詳細な情報を表示してくれる.

mkbka001(500)$ ls -l
total 40
drwx------ 2 g0123456 student 8 5 13 00:49 Desktop
drwx------ 2 g0123456 student 8 4 14 14:22 Documents
drwxr-xr-x 2 g0123456 student 15 4 14 17:59 Downloads
drwx------ 28 g0123456 student 33 5 13 01:53 Library
drwx------ 2 g0123456 student 3 4 14 14:22 Movies
drwx------ 2 g0123456 student 3 4 14 14:22 Music
drwx------ 2 g0123456 student 4 4 14 14:22 Pictures
drwxr-xr-x 3 g0123456 student 4 4 14 14:22 Public
drwxr-xr-x 3 g0123456 student 5 4 14 14:22 Sites
-rwxr-xr-x 1 g0123456 student 1035 4 25 13:32 a.out
-rw-r--r-- 1 g0123456 student 125 4 25 2008 log
drwxr-xr-x 2 g0123456 admin 9 4 6 13:20 public_html
-rw-r--r-- 1 g0123456 student 68 4 25 2008 sample.c
-rw-r--r-- 1 g0123456 student 0 4 25 2008 sample.txt
mkbka001(501)$

各行が各ファイルの詳しい情報を示しているが,その読み方は以下の通り.

UNIXのファイルに対する権限は,ファイルにアクセスしようとするユーザを「所有ユーザ」「所属グループ」「その他の無関係なユーザ」という3つの分類で分けた上で,それぞれの分類に対して,「内容の読み取り権(read)」「内容の書き込み・修正権(write)」「プログラムとしての実行権(execute)」という3種類の権限を与える・与えないという方針で決定される.各権限が与えられていれば,アルファベットr,w,xで示され, - 記号は権限が与えられていない事を示している.

例えば,上の図のa.outファイルの場合,このファイルの所有ユーザg0123456は,ファイルの読み取り,書き込み・プログラムとしての実行が可能だが,studentグループに所属する(他の)ユーザに対しては,読み取りと実行だけが許されており,その他のユーザには読み取りと実行が許可されている事を示す.

このファイルに対する各種権限のことをパーミッション (permission)と呼ぶ.パーミッションの詳細については,後日,もう少し説明を行う (I'll be back....)

隠しファイルの表示

ファイル名の先頭がピリオド (.) で始まるファイルは,単なるlsコマンドでは表示されない「隠しファイル」として扱われる.(尚,このようなファイルはFinder上でも表示されない.)

それら隠しファイルを含めてファイル一覧を得るには,-aオプションを付けてlsコマンドを実行する.

ls -a

例えば,ホームディレクトリでls -aを実行すれば,このような表示が得られるだろう.

.                               .xsession
..                              Desktop  
.CFUserTextEncoding             Documents
.DS_Store                       Downloads
.Mac OSX                         Library   
.TemporaryItems                 Movies   
.Trash                          Music   
.Xauthority                     Pictures  
.bash_history                   Public   
.bash_logout                    Sites   
.bash_profile                   a.out   
.bashrc                         log   
.config                         public_htm
.cups                           sample.c  
.emacs.d                        sample.txt
.emacs.el                      

ホームディレクトリに置かれた隠しファイル(ドットファイルとも呼ばれる)は,各種のシステム設定を行う為のファイルである場合が多く,ユーザ登録時に予め配布されたものもあれば,ソフトウェアを使っていくうちに自動作成されるものもある.従って,よく分からないまま,無闇に削除することは控えたほうが良く,どうしても削除する場合には削除しても差し支えがないことをしっかり確認してから行うようにしよう.

また,これらの隠しファイルの「詳細情報」が見たければ ls -la コマンドを実行すれば見る事が出来る.

Mac OS Xの不思議な仕様その1

ディレクトリとはMac OS Xではフォルダに相当すると説明した.既に気がついている者もいるはずだろうが,Mac OS XでファイルをGUIで操作するのはFinderによるが,このFinderのフォルダ名表示とターミナルでのファイル名表示が食い違って見える.

Finderウィンドウを一枚開き,デスクトップ上の家型アイコンをクリックして各自のホームフォルダ(ホームディレクトリ)を開いてみよう.そこに一覧表示されたファイルやフォルダ(ディレクトリ)の名前とターミナル上でlsコマンドを実行して表示されるファイル名一覧を比べてみよう.恐らく,幾つかのフォルダ名が食い違っているはずである.

この理由は,Mac OS XがFinder上でフォルダ名を画面表示する際,元々英語名で付けられている名前を「翻訳」して表示する仕様になっているからである.例えば,

Library -> ライブラリ
Desktop -> デスクトップ
Documents -> 書類

などである.

こんな小細工をする必要性が個人的には理解できないが,これがMac OS XのFinderの仕様となっているから仕方がない.「ディレクトリ名が食い違ってる!」などと慌てないようにしよう.尚,これらのディレクトリはMac OS Xが正常に動作するために不可欠であることがあるので,名前を変えたり削除したりしないように注意して欲しい.

ちなみに,Mac OS Xは標準でフランス語や中国語など多言語環境に対応しており,システムの設定を少し変えれば例えば中国語の画面表示で利用することが出来る.その場合,これらのフォルダ名は「中国語に翻訳」されて表示されるそうである.

Mac OS Xの不思議な仕様その2

ファイル名の末尾に . (ピリオド)に続けて2〜3文字のアルファベットが付けられる事がある.これを拡張子 (Extension)と呼び,ファイルの種類を識別する手がかりとされている.Windowsでは,この拡張子はシステムがファイルを適切に取り扱うために重要な役割を果たしているのに対し,UNIXではファイル名に拡張子を付けることは殆ど意味がなく,自由にファイル名を付けられる.

ところが,Mac OS Xでは,その誕生と発展の歴史からUNIXとしての特性とMac OS X以前のMac OSとの互換性を引き継ぐという,やや渾沌とした状況にある.

UNIX由来のソフトウェアはファイル名に特に制約がない.
以前のMac OSとの互換性を持つソフトウェアもファイル名に特に制約がない.
最近のMac OS Xに対応したソフトウェアだと,ファイル名の拡張子に意味がある(らしい).

という状況であり,まったく一貫していない.

これに輪をかけて,ややこしくしているのがMac OS XのFinder上のファイル名表示が「標準状態では拡張子を全部表示しない」というものである.Finderのメニューから「環境設定」を選択し,表示されるウィンドウの「詳細」タブをクリックしてみよう.cse環境では,以下の状態となるように調整してある.

ここで「すべてのファイル名拡張子を表示」にチェックマークが入っている事を確認しておこう.

これによりFinderのファイル名表示において確実に拡張子を表示してくれるから,ターミナル上でlsコマンドによりファイル名一覧を表示させた場合との相違が無くなるので好都合である.尚,この設定は,明示的に調整しないと設定されないから,各自,自分のMacBookをローカルブートした個人環境でのFinderの環境設定も,是非とも同じ設定となるように調整しておくことを強くお勧めしておく.

ファイルの複製 (copy)

ターミナル上でファイルの複製操作を行うのはcpコマンドである.使い方は

cp 元ファイル 複製先

となる.例えば,programという名前のディレクトリがカレントディレクトリである場合,

cp hello.c draw.c

と実行すると,下図のようにファイルが複製される.

また,programディレクトリにbackupディレクトリがあり,そのディレクトリ配下に複製する場合には,

cp hello.c backup/draw.c

となる.

少し分かりにくいが,cpコマンドの最初の引数がファイル,二つ目の引数がディレクトリの場合,つまり

cp hello.c backup

と実行した場合は,そのディレクトリの下に複製元ファイルが同じ名前で複製されるという約束になっている.

ファイルのディレクトリ間移動とファイル名の変更 (move)

ファイルの配置ディレクトリを変えて移動させるのはmvコマンドである.

mv 移動対象ファイル 移動先

と実行する.例えば,カレントディレクトリprogramにあるファイル hello.c をディレクトリ backup に移動させるには,

mv hello.c backup

と実行する.

尚,mvコマンドはファイルの単なる移動だけでなくファイル名の変更も合わせて行うことができる.例えば,カレントディレクトリにあるファイル hello.c をディレクトリ backup に移動させ,しかもファイル名を bar.c に変更するには,

mv hello.c backup/bar.c

と実行する.

ところで,mvコマンドは「ファイル名変更」に使うと既に説明した.これはどのように考えたら良いのだろう.これは,「同じディレクトリ中の移動」として考えれば良い.

例えば,カレントディレクトリにあるファイル sample.c を foo.c に名前を変更するには,

mv sample.c foo.c

とすれば良い事は既に知っているはずである.

ディレクトリの作成 (make directory)

ファイルを整理する為,新しいディレクトリを作成するには,mkdirコマンドを用いて,

mkdir ディレクトリ名

と実行する.例えば,カレントディレクトリに backup というディレクトリを作成するには,

mkdir backup

と実行する.

尚,このディレクトリの作成はカレントディレクトリでなくとも可能である.例えば,カレントディレクトリにあるbackupディレクトリ配下にtempディレクトリを配置するには,

mkdir backup/temp

と実行する.

ディレクトリの削除 (remove directory)

不要となったディレクトリはrmdirコマンドで削除出来る.

rmdir ディレクトリ名

但し,ディレクトリが空の状態でないと削除できない.

作業ディレクトリの変更 (change directory)

ターミナル上で作業中にその時点での作業場所となっているディレクトリをカレントディレクトリと呼ぶが,この作業ディレクトリを他のディレクトリに変更することを,「カレントディレクトリを移す」とか「カレントディレクトリを移動する」と呼ぶ.(ちなみにカレント (current)とは「今現在の」という意味の英単語である.)

カレントディレクトリを移動するには,cdコマンドを用いて以下のように実行する.

cd 移動先ディレクトリ

例えば,カレントディレクトリがprogramである時,その下にあるbackupディレクトリにカレントディレクトリを移すには,

cd backup

と実行する.

又は,

cd ./backup

としてもよい.

ディレクトリ操作のためのコマンドまとめ

TABキーによるファイル名補完機能について

Mac OS Xで標準で採用されているbashには,ファイル名補完機能と呼ばれる便利な機能が備わっている.絶対パス名や特に長いファイル名などをキー入力する場合,ファイル名の先頭数文字を入力した時点でTABキーを押すと,残りのファイル名を自動的に補ってくれる.上手に使ってタイプ入力の手間や間違いを効果的に減らすようにしよう.

本日の練習問題

以下の順番でディレクトリやファイルの移動を行ってみよ. 特にカレントディレクトリやファイルが配置されているディレクトリ位置を頭に思い浮かべながら操作すること. 適当なメモ用紙にディレクトリとファイルの配置関連図を書きながら操作すると理解しやすい.

注: 理解が遅い人ほど,この「配置図を書く」という手間を惜しんで(或いは,メモ用紙がもったいないのか?)頭の中だけで理解しようと奮闘するらしい.これが災いして,逆になかなか分からず苦しんでいる者がよく見かけられる.「急がば回れ」という諺を知らないらしい....

まず準備としてターミナルを新しく一枚開き,次のコマンドを実行せよ.

pwd

これで各自のホームディレクトリの絶対パスが表示される.この段階で,まず,各自のホームディレクトリとrootディレクトリ,及び,途中にあるディレクトリ間の配置関係図をメモ書きしてみよ.

次に以下のコマンドを実行せよ.

date >> english.txt

次に,lsコマンドを実行して,english.txtという名前のファイルが存在していることを確認せよ

ls

english.txtが存在していることが確認できたら,先に書いたディレクトリ配置のメモにenglish.txtを表す部分を付け加えて書いてみよ.

ここまで準備したらターミナル上のシェルに対して以下の練習問題のファイル操作を行ってみよ.

練習問題はこちらをクリック

基礎プログラミング演習Iの表紙ページへ戻る