ディレクトリツリーとファイルパス

ここまでの説明で、UNIXのファイルシステムは、最上位の/からディレクトリが階層的に作られて分類されていることが分かったと思う。図で表すと次のようになる。

このような、1つの根元から枝分かれしているように見えることから(見えなかったらひっくり返して見よう)、このような構造は「ツリー構造(木構造)」と呼ばれる。また、/は根元に相当するのでルートrootと呼ばれる。

ファイルパス

ファイルシステム中のファイルやディレクトリの所在地を書き表す方法について説明する。考え方としては、ある場所を起点として、目的地となるファイルやディレクトリまでの経路(path)を記述する。起点をルートとするか、現在着目している場所とするかで、2種類の記述方法がある。

絶対パス

「絶対パス absolute path」あるいは「フルパス full path」は、起点をルート/とし、ルートからどのように辿るかを記述する方法である。ちょうど住所を書くのに、都道府県から全部書くような感じである。

/から順にディレクトリを指定し、ディレクトリの区切りには/を書く。

例えば上の図中のusrディレクトリの中の、binディレクトリの中の、calというファイルならば、それぞれ絶対パスで図中の赤色の文字のように表記できる。

練習 上の図の"homework.txt"を絶対パスで書いてみよう。

相対パス

絶対パスを使うと任意の位置のファイルを一意的に指定できる。しかし、実用的には面倒だったり不便なこともある。

例えば住所で考えてみよう。京都に住んでいる人が「北区」と言えば、普通は京都市の北区を指すだろう。実際には日本にはたくさん北区があるのだが、いちいち「京都府京都市北区」なんて書くのは面倒である。あるいは、隣にいる山田さんを言いたければ、いちいち「京都府京都市北区上賀茂本山にいる山田さん」と言うよりも単に「隣の山田さん」と言った方が楽だ。また、山田さんと一緒に移動する限りは、どこに行っても「隣の山田さん」で指すことができる。

このように、自分がいまいる場所から目的の位置に行くまでの経路を表すのが相対パスである。ファイルシステムにおいて、自分がいる場所、というのは、現在作業しているディレクトリ、すなわちカレントディレクトリのことである。

整理すると、相対パスrelative pathとは、カレントディレクトリを起点とし、目的のファイルあるいはディレクトリまでの経路を記述する方法である。

カレントディレクトリから下の位置を指す場合は、単にファイル名やディレクトリ名を書けばよい。ディレクトリのさらに中を指す場合は/でつないで書いていく。例えば下図において、カレントディレクトリが/Users/g123456の時、homework.txtの相対パスはDocuments/homework.txtとなる。最初に/を書かないことに注意!!書いてしまうと絶対パスになってしまう。

カレントディレクトリより上のディレクトリを表したい場合はどうすればよいか?この場合、..(ピリオドを2個続けて書く)を使う。..は「一つ上」を意味する書き方である。一つ上のディレクトリを親ディレクトリと呼ぶこともある。

例えば、カレントディレクトリが/Users/g123456の時、一つ上の/Usersは相対パスで、単に..と書き表される。さらにもう一つ上の/は、「一つ上の一つ上」だから、../..と書ける。

一旦上に上がってからその中のディレクトリに下がる場合は、そのまま/でつなげて書いていけばよい。例えば/binは、カレントディレクトリ/Users/g123456から見ると「一つ上の一つ上の中のbin」であるから、../../binとなる。

練習 上の図で、カレントディレクトリが/Users/g123456の時、/usr/bin/calを相対パスで書いてみよう。

なお、カレントディレクトリを表したい場合は.(ピリオド1個)と書く。

ls -aで隠しファイルも含めて表示させると、.と..が表示されるが、これらはここで説明したカレントディレクトリと親ディレクトリである。

ホームディレクトリ

各ユーザの自分のファイルの置き場所は決まっていて、macOSの場合は「/Users/ユーザ名」となっている。これをホームディレクトリと呼ぶ。ターミナルでウィンドウを開きシェルを起動した直後はカレントディレクトリはホームディレクトリとなっている。ユーザはシステムのファイルや他のユーザのファイルを操作する必要は少なく、自分のファイルを操作することの方が多いので、ホームディレクトリは作業の起点となる。

ホームディレクトリを指す書き方として、~(チルダ)が用意されている。上の図の例では、/Users/g123456がホームディレクトリだとすると、これを単に~と書ける。~は相対パスに使うことができる。カレントディレクトリがどこであろうと、homework.txtは~/Documents/homework.txtと書ける。

~が表すディレクトリは、ユーザごとに異なることに注意。ユーザGuestさんにとっては~は/Users/Guestになるので、~/Documents/homework.txtは存在しないことになる。なお、特定のユーザを指定してホームディレクトリを指したい場合には「~ユーザ名」という書き方もある。ユーザGuestが~g123456/Documents/homework.txtと指定すると、/Users/g123456/Documents/homework.txtのことになる。

ディレクトリ操作関連のコマンド

ディレクトリを作成する

ディレクトリを作成するにはmkdirコマンド(make directory)を使う。

mkdir 作成するディレクトリ名

指定したディレクトリ名と同じ名前のディレクトリあるいはファイルが既に存在していた場合は"File exists"と表示され、何も起こらない。

練習 ホームディレクトリにprogramという名前のディレクトリを作成せよ。既にprogramという名前のディレクトリが存在する場合は別の名前にすること。

ディレクトリを削除する

ディレクトリを削除するにはrmdirコマンド(remove directory)を使う。

rmdir 削除するディレクトリ名

ただし、削除するディレクトリは空、つまり中にファイルやディレクトリが無い状態でなければ削除できない(Directory not emptyと表示される)。なお、一見空に見えても隠しファイルが存在することがあるので注意。Finderは自動的に隠しファイルを作ることがあるので、ターミナルで作成したディレクトリをFinder上で操作するとrmdirコマンドで消せなくなる場合がある。

rmコマンドに-dオプションを付けるとディレクトリも削除できるようになる。また、rmコマンドに-rオプションを付けると、指定したディレクトリ以下のファイルを全部消すことができるが、うっかり間違って必要なファイルまで消してしまわないよう注意。

カレントディレクトリを変更する

カレントディレクトリを変更するにはcdコマンド(change directory)を使う。

cd 変更先のディレクトリ

変更先のディレクトリの指定は、絶対パスでも相対パスでもよい。変更先のディレクトリを省略する(つまりcdだけでコマンドを実行する)とホームディレクトリに移動する。

練習 先ほど作成したディレクトリprogramにカレントディレクトリを変更せよ。

カレントディレクトリを表示する

pwdコマンド(print working directory)でカレントディレクトリを表示できる。

pwd

ファイル操作を行っているどこで作業しているのか忘れてしまいがちなので時々pwdして確認するとよいだろう。pwdコマンドは副作用がないので安心して頻繁に使うとよい。

FPSなどのゲームでは周囲の状況を把握することが重要である。コマンド操作も同じように、自分が今どこにいて、どのようなファイルが存在するのかを常に確認するためにpwdとlsコマンドを活用しよう。

練習 カレントディレクトリを表示せよ。

カレントディレクトリが/Users/g123456/program (ただしg123456の部分は自分のMacのアカウント名)になっていない場合は次のコマンドを実行すること。

% cd ~/program

練習 次の練習に備えて次の4つのコマンドを実行せよ(>>の意味は次回説明する)。最後のlsコマンドで、backupとhello.cとbye.cが出来ていることを確認すること。

% mkdir backup
% date >> hello.c
% date >> bye.c
% ls

ディレクトリをまたいだファイル操作

既に紹介したファイル操作コマンドではファイル名を指定していたが、ファイル名は絶対パスあるいは相対パスを使ってディレクトリ込みで指定できる(単にファイル名だけ書いていたのは相対パスの一種)。異なるディレクトリ間でファイル操作したり、ディレクトリ名を指定した場合にどうなるかを説明しておこう。

mvコマンドの場合

mvコマンドはファイル名を変更するコマンドと説明したが、正確には、あるファイルのパスを変更するコマンドである。

mv 元のファイルパス 変更後のファイルパス

例えば、下図のようなファイル構成で、カレントディレクトリがprogramの時に、hello.cをbackupの中に移動させることを考えてみる。

ここまでの練習でこの図の状態になっているはずである。

それぞれの相対パスを考えると、元のパスはhello.c、移動後のパスはbackup/hello.cとなるので、次のコマンドで移動できる。

% mv hello.c backup/hello.c

ここで、ファイル名自体が変わらない場合は省略してディレクトリ名だけ書くことができる。

% mv hello.c backup

ただし、このように書けるのはbackupというディレクトリが既に存在している場合のみである。もしbackupというディレクトリが無かったら、通常のファイル名として名前が変更される。綴りを間違うなど、よくやってしまうミスである。ディレクトリ名を指定する場合は最後に/を付けるようにするとミスを防ぐことができる。なお、tabキーを使ってファイル名やディレクトリ名を補完表示させるとムダなタイプミスをしなくて済むので積極的に使おう。

% mv hello.c backup/

練習 上記のいずれかのコマンドでhello.cをディレクトリbackupの中に移動させよ。

移動後は下図のような構成になる。

パスを変更するので、ファイル名も同時に変更することもできる。例えば、backupの中に移動してファイル名をhello_old.cに変更したい場合、

% mv hello.c backup/hello_old.c

とすればよい(下図のようになる)。

以上の例は相対パスで説明したが、絶対パスでも同様である。

cpコマンドの場合

cpコマンドもmvコマンドと同様である。ファイルのパスの書き方次第でディレクトリをまたいで複製することもできる。

cp 元のファイルパス 複製後のファイルパス

例えば、下図のようにコピーしたい場合、

次のコマンドとなる。

% cp hello.c backup/hello.c

mvコマンドと同様にファイル名が同じでよいならディレクトリ名だけ指定してもよい。

% cp hello.c backup/

当然、名前も変更してコピーできる。

% cp hello.c backup/hello_old.c

練習 bye.cをbackupの中のbye_old.cという名前として複製せよ。

練習 ディレクトリprogram以下を削除せよ。上の練習までの状態ならコマンドは例えば次のようになる。

% cd backup/
% rm hello.c
% rm bye_old.c
% cd ..
% rm bye.c
% rmdir backup/
% cd ..
% rmdir program/

どうしてもうまく消せない場合はFinderでホームディレクトリを開き、その中のprogamフォルダを削除すればよい。あるいは授業スタッフを呼んで消してもらうこと。

複数のファイルをまとめて指定する方法や、あるディレクトリ以下を全部まとめて消すオプションもあるが、少々危険なためここでは説明しない。「よく使うUNIXコマンド集」には書いてあるので、本格的にコマンドを使い始めたら、確認して使いこなしてほしい。