基本的なUNIXコマンド
1 概要
前回は、FreeBSDにログインしてシャットダウンするコマンドを紹介しました。 それだけでは起動してすぐ終了する以外にできることがありません。 今回は、ファイルとディレクトリに関するコマンドを扱います。 取り扱うのはごく基本的なものだけです。
先にどのようなもの扱うか示してしまいます。
- ls
- cd
- pwd
- mkdir
- rmdir
- cat
- cp
- mv
- rm
まずはこれだけです。これだけ覚えれば最初の目標のHello Worldのプログラムを実行させるのに十分です。
2 UNIXのファイルシステムについて
コマンドの説明に入る前に、UNIXのファイルシステムについて触れておきます。 ファイルシステムと言うと、SSDやハードディスクをフォーマットした経験のある人は、FAT32とかNTFSといったフォーマットの形式のことを想像されるかもしれません。 ここで話そうとしているのはそのフォーマットの形式のことではありません(まったく無関係なわけでもありませんが、扱いません)。 UNIXがシステムの情報や設定やプログラムをどのように保持しているのか、そしてユーザーが作成したものをどのように保持するのかについてです。 UNIXはそういったものをツリー構造(木構造)に構造化して管理しています。
といっても言葉では伝わりづらく、絵で見た方が理解しやすいと思い作成しました。
FreeBSDの実際のファイルシステムの構造をイメージしたものです。
これで全てではなく、たくさん省略しています。
まず注目すべきは、一番上に /
というのがあることです。
これはルートと呼ばれます。
上の図の、四角で囲まれたそれぞれの節は、ディレクトリです。
/
は、ルートにあるディレクトリなのでルートディレクトリと呼ばれます。
ディレクトリとは何なのかというところですが、直感的にはWindowsやmacOSのフォルダのようなものを想像してもらってOKです。
ディレクトリの中には、またディレクトリを含んだりできます。
上の図では、 usr
の中に、また色々とディレクトリを含んでいます。
このようなあるディレクトリの 下の階層にある ディレクトリをサブディレクトリと呼びます。
上の図では省略していますが usr
以外のディレクトリにもサブディレクトリはたくさん存在します。
UNIXのファイルシステムにおいては、すべてはルートディレクトリのサブディレクトリになっています。
図の一番左側にある bin
というディレクトリに注目してみましょう。
このディレクトリを指定するには /bin
のように指定します。
これで「ルートの直下にあるbinだ」ということが明確になります。
今度は usr
の下の一番左側にある bin
というディレクトリに注目してみましょう。
このディレクトリを指定するには /usr/bin
のようにします。
/bin
と /usr/bin
は全く別物です。
ディレクトリ名が同じでも、直接含まれるディレクトリが異なります。
直接含んでいるディレクトリ、別の言い方をすればひとつ上ディレクトリを親ディレクトリ; Parent Directoryと呼びます。
また、 /bin
や /usr/bin
のように、目当てのディレクトリまでに経由するディレクトリをスラッシュ区切りで並べたものをパスと呼びます。
UNIXのファイルシステムにおいて、すべてのディレクトリはパスによって一意に識別することができます。
似たような手法として、WebブラウザでアクセスするURLが、重複することなく、世界で唯一のものになっていることが考えられるかもしれません。
しかし、UNIXのパスが一意なのはそのシステム内に限ったことで、世界で唯一なものではありませんし、そんなことを要求する意味はありません。
フォルダの中にファイルを保存したりできるのと同じように、ディレクトリの中にファイルを保存することができます。
例えば、C++のヘッダーファイル iostream
は /usr/include/c++/v1
というところに格納されていて、そのパスは /usr/include/c++v1/iostream
です。
ファイルのパスもディレクトリのパスも同じように指定できます。
パスの記述の仕方からは、ファイルを指しているのかディレクトリを指しているのか区別できないため、戸惑うかもしれません。
これにはあまり有効な解決策がないように思います。
とにかくシステムを使い込んで身体に染み込ませる必要があります。
ファイルシステムについてはこれくらいで終っておきます。
3 カレントディレクトリを知る: pwd
まずpwdという簡単なコマンドから始めます。 pwdは現在のディレクトリのパスを表示するもので Print Woring Directory の略です。 「ピー・ダブリュー・ディー」と発音する人が多いかと思いますが、ちょっと長いので脳内では「パウド」と再生しています。 現在のディレクトリとは何かというと、今作業をしている場所です。
例え話をすると、ある建物の清掃作業をしているとします。 作業を記録するために、今自分がどこの場所で作業しているのかをメモしておく必要があるとします。 作業をしている最中は「1階のロビー」とか「3階の会議室」とか「5階の秘密の部屋」とか「屋上の休憩スペース」とか、常に作業している場所をというものがあります。 FreeBSDを使っているときも似たような感じで、常に作業中の場所というのがあります。 ただし、作業中の場所はファイルシステムのパスで表されます。 usrのincludeで作業しているときは「/usr/include」と表します。 この現在作業中の場所のことを、カレントディレクトリまたはワーキングディレクトリと呼びます。
カレントディレクトリの仕組みがあると色々と便利なことがあります。 その一つがパスをルートから全部指定しなくても、カレントディレクトリを始点として指定することができるというものです。 先の清掃作業の例えを使うと、「3階の会議室の窓側のテーブル」と言う代わりに、現在作業中の場所が3階の会議室なら、「窓側のテーブル」とだけ言うことができます。 同じように、「/usr/include/c++」と言う代わりに、カレントディレクトリが/usr/includeならば、「c++」とだけ言うことができます。 この例のような短かいパスの場合それほどありがたみがないかもしれません。 しかし、実際の作業においてはパスはとても長くなるので、とても全部指定するやり方ではやってられません。 清掃作業の例では建物の階を指定するところから始めましたが、もし、建物の正確な位置から指定しないといけないとしたらどうでしょう。 「X県Y市Z町11-22-33の3階の会議室のテーブル」のようになって、大変です。 一方で、本当に正確な位置が必要な場合もあり、その場合は正確な位置を伝える必要があります。 このことはパスの指定においても当てはまります。
「/usr/include/c++」のようにルートを始点として表現するパスを絶対パスと呼びます。 カレントディレクトリが/usr/includeのとき、その場所を始点として「c++」のように表現するパスを相対パスと呼びます。
pwdはカレントディレクトリの絶対パスを表示します。
ログインした状態で pwd
とキーボードでタイプしてみます。
root@freebsd:~ # pwd⏎ /root root@freebsd:~ # ▋
カレントディレクトリが /root
であることが分かります。
/root
というディレクトリはrootというユーザーのホームディレクトリです。
ホームディレクトリはそのユーザーのために用意された専用のディレクトリです。
ユーザーの日常的な作業やファイル保存などはホームディレクトリの中で行うのが基本です。
pwdコマンドはあまり面白いものではないかもしれませんが、使用頻度はかなり高いです。 「今どこで作業してるんだっけ?」という状況はそこそこあったりしたり、なんとなく手の空いたときなどに自然とタイプしてしまうからです。
現段階では作業場所を変更する手段がないため、常に /root
と返すだけなのでこれ以上使い道はありません。
次に進みましょう。
4 ディレクトリの内容を表示する: ls
ディレクトリの中にはファイル、またはサブディレクトリを入れておくことができます。 ちょうどWindowsやmacOSでフォルダの中にファイル、またサブフォルダを入れておくことができるのと同じような感覚です。 ディレクトリの中に何が含まれているのか確認するためのコマンドが存在します。 それがlsです。
lsはおそらく最も使用頻度の高いコマンドのひとつでしょう。
コマンドラインでの作業では、常にディレクトリの中身を表示させておくことができないので、どんなものが含まれているか知りたくなったらその都度 ls
と打たなければいけません。
最初は面倒に感じるかもしれませんが、コマンドラインを使い込んでいくうちに無意識に ls
と打っているようになります。
使用例を見てみます。
FreeBSDにログインしておいて下さい。
まず現在のディレクトリがホームディレクトリ /root
であることを確認しておきます。
root@freebsd:~ # pwd⏎ /root root@freebsd:~ # ▋
この場所で ls
と打つとどうなるのか試してみます。
root@freebsd:~ # ls⏎ .cshrc .k5login .login .shrc .history .lesshst .profile root@freebsd:~ # ▋
表示された内容をみると、ディレクトリ /root
には7つのファイルが存在していることが分かります。
- .cshr
- .k5login
- .login
- .shrc
- .history
- .lesshst
- .profile
これらのファイルが何なのかは気になるかもしれませんが、今は無視しておきます。
重要なのは、単に ls
と打つと、カレントディレクトリにあるファイルの一覧が得られるということです。
lsという名前は LiSt の略だと思われます。
もしlsがカレントディレクトリの内容しか表示できないとしたら、あまり面白いものではありません。
pwdと違ってlsは任意の場所のディレクトリの内容を表示することができます。
カレントディレクトリ以外の場所の内容を表示するには ls
の後に1つ以上のスペースを入れて、ディレクトリのパスを続けて指定します。
ルートディレクトリ /
指定するには次のようにします。
root@freebsd:~ # ls /⏎ .cshrc boot lib proc usr .profile dev libexec rescue var .snap entropy media root COPYRIGHT etc mnt sbin bin home net tmp root@freebsd:~ # ▋
/usr
を指定するには次のようにします。
root@freebsd:~ # ls /usr⏎ bin include lib32 libexec obj share tests home lib libdata local sbin src root@freebsd:~ # ▋
複数のディレクトをまとめて指定することもできます。
root@freebsd:~ # ls /usr /bin⏎ /usr: bin include lib32 libexec obj share tests home lib libdata local sbin src /bin: [ df kill ps sh cat domainname link pwait sleep chflags echo ln pwd stty chio ed ls realpath sync chmod expr mkdir red tcsh cp freebsd-version mv rm test csh getfacl pax rmail unlink date hostname pgrep rmdir uuidgen dd kenv pkill setfacl root@freebsd:~ # ▋
ls directory1 directory2
のように、コマンド名に続けて追加で指定するものをコマンドライン引数、あるいは単に引数と呼びます。
何を引数として指定するのかは、そのコマンドによって異なります。
lsの場合、引数は内容を表示したいディレクトリでした。
lsのやってくれる仕事は コマンドライン引数に指定されたディレクトリの内容を表示する である、と言うことができます。
そして、コマンドライン引数が省略された場合のみ、カレントディレクトリの内容を表示する、という特別な振舞いをすると考えるのが妥当です。
カレントディレクトリの内容を表示したいという状況はとても多いので、便利なようにこのようなデフォルトの動作が用意されています。
lsについてはもうちょっと知っておくべきことがあります。
それはコマンドラインオプション、あるいは単にオプションです。
オプションは -a
や -l
のように、ハイフン(あるいはダッシュ、マイナス)に続けてアルファベットか数字の一文字を繋げたものです。
オプションの指定方法にはこれだけではないのですが、最もよくあるのはこの形式です。
オプションを指定するとコマンドの動作に変更を加えることができます。
lsに -l
を指定した場合の例を見てみます。
root@freebsd:~ # ls -l /⏎ total 85 -rw-r--r-- 2 root wheel 1023 Apr 9 2021 .cshrc -rw-r--r-- 2 root wheel 507 Apr 9 2021 .profile drwxrwxr-x 2 root operator 512 Apr 9 2021 .snap -r--r--r-- 1 root wheel 6109 Apr 9 2021 COPYRIGHT drwxr-xr-x 2 root wheel 1024 Apr 9 2021 bin drwxr-xr-x 14 root wheel 1536 Dec 30 16:56 boot dr-xr-xr-x 17 root wheel 512 Dec 30 16:59 dev -rw------- 1 root wheel 4096 Dec 30 16:59 entropy drwxr-xr-x 27 root wheel 2560 Dec 30 23:29 etc drwxr-xr-x 5 root wheel 1536 Apr 9 2021 lib drwxr-xr-x 3 root wheel 512 Apr 9 2021 libexec drwxr-xr-x 2 root wheel 512 Apr 9 2021 media drwxr-xr-x 2 root wheel 512 Apr 9 2021 mnt drwxr-xr-x 2 root wheel 512 Apr 9 2021 net dr-xr-xr-x 2 root wheel 512 Apr 9 2021 proc drwxr-xr-x 2 root wheel 2560 Apr 9 2021 rescue drwxr-x--- 2 root wheel 512 Dec 31 01:19 root drwxr-xr-x 2 root wheel 2560 Apr 9 2021 sbin drwxrwxrwt 6 root wheel 512 Dec 30 16:59 tmp drwxr-xr-x 15 root wheel 512 Dec 30 16:57 usr drwxr-xr-x 24 root wheel 512 Dec 30 16:59 var root@freebsd:~ # ▋
何やらいかめしい表示がされて目を背けたくなるかもしれません。 簡単に触れておきます。
- 先頭に
d
とついているものは、その行の項目がディレクトリであることを示しています。 - 一番後ろの列に表示されているのが、ファイルもしくはサブディレクトリの名前です。
- そのひとつ前に表示されているのが、そのファイルもしくはサブディレクトリが最後に更新された日付になっています。
他にも重要な情報があるのですが、ここではこれ以上詳しくは扱いません。
最後にもうひとつ付け加えてlsを締め括りたいと思います。 それは、lsの引数にファイルを指定したらどうなるのだろうか、ということです。 実際にやってみるのが早いでしょう。
root@freebsd:~ # ls .cshrc⏎ .cshrc root@freebsd:~ # ▋
単にファイル名だけが表示されました。 びっくりするほどのことではないかもしれません。 しかし、この情報が何の役に立つのだろう、と疑問に思われるかもしれません。 実はシェルとワイルドカードの扱いを覚えると、この動作はとても理に適っていることが分かるのですが、またしばらく先の楽しみとして残しておきます。
オプション -l
の使い方を覚えたので、これを指定してみます。
root@freebsd:~ # ls -l .cshrc⏎ -rw-r--r-- 2 root wheel 1023 Apr 9 2021 .cshrc root@freebsd:~ # ▋
今度はいくらか役に立ちそうな情報が表示されました。 ここで言いたかったのは、lsはディレクトリだけでなくファイルも扱えるということです。 当然だろうと思ったら気にせず軽く流しておいてください。
これでlsを終わります。
5 ディレクトリを渡り歩く: cd
理屈の上では、すべてを現在のディレクトリを始点として指定することでも、あらゆる作業を行うことが可能かもしれません。 しかし、実用上は大いに問題があります。
例えばカレントディレクトリがrootのホームディレクトリである /root だとして、そこに projects/program1 と projects/program2 があったとします。
program1とprogram2の中には、それぞれfile1、file2、file3…のようにたくさんのファイルがあるとします。
今作業しているのはprogram1で、program2は20年後に開始する予定のプロジェクトだとします。
もしカレントディレクトリを変更することができなかったら、program1のファイルにアクセスするために、常に ls -l projects/program1/file1
や ls -l projects/program1/file2
のように長々と指定しなければなりません。
これよりは ls -l file1
や ls -l file2
のように指定できた方が遥かに便利です。
カレントディレクトリがワーキングディレクトリとも呼ばれるのは、こうしたように 今まさに作業しているディレクトリ を意味しているからです。
作業ディレクトリを変更することで、その配下にあるファイルやディレクトリへのアクセスを楽にすることができます。
カレントディレクトリ、つまり作業ディレクトリを変更するにはcdコマンドを使います。
cdは Change Directory の略です。
試してみます。
root@freebsd:~ # cd /usr⏎ root@freebsd:/usr # pwd⏎ /usr root@freebsd:/usr # ls⏎ bin include lib32 libexec obj share tests home lib libdata local sbin src root@freebsd:/usr # ▋
もっと奥深くへ潜ってみます。
root@freebsd:/usr # cd /usr/include/c++/v1/experimental⏎ root@freebsd:/usr/include/c++/v1/experimental # pwd⏎ /usr/include/c++/v1/experimental root@freebsd:/usr/include/c++/v1/experimental # ▋
かなり深い所まで来ました。
ところで、これだけ目立つと、もうプロンプトのところが変化していることに気付いたと思われます。 実は現在設定されているデフォルトのプロンプトには、カレントディレクトリのパスを表示するような設定がなされています。 プロンプトはシェル機能で、ユーザーが変更することもできます。 今のプロンプトにはパスが表示されているので、cdするたびに毎回pwdを打ち込む必要性はあまりないでしょう。
潜ったディレクトリで ls
を打ち込んでみます。
root@freebsd:/usr/include/c++/v1/experimental # ls⏎ __config filesystem map simd utility __memory forward_list memory_resource string vector algorithm functional propagate_const type_traits coroutine iterator regex unordered_map deque list set unordered_set root@freebsd:/usr/include/c++/v1/experimental # ▋
いったん作業ディレクトリを変更したら、そこを始点に相対パスでファイルやディレクトリを指定できるという特典が付いてきます。
cdに限ったものではないですが、パスを指定するのに知っておくべき便利な、というより必須の方法があります。
..
とすると、その位置から一つ上のディレクトリを指すようになります。
なので cd ..
とすると、カレントディレクトリから一つ上のディレクトリ(親ディレクトリと呼びます)に移動できます。
root@freebsd:/usr/include/c++/v1/experimental # cd ..⏎ root@freebsd:/usr/include/c++/v1/ # pwd⏎ /usr/include/c++/v1 root@freebsd:/usr/include/c++/v1 # ▋
パスの一部として組み合わせて使うこともできます。
なので ls -l ../../sys/types.h
のような指定も可能です。
..
が親ディレクトリを指すのに対して .
というのもあって、これはカレントディレクトリを指します。
なので ls -l ./././
のような指定も可能です。
ls -l
と同じであり、そうする意味はありませんが。
.
も必要になることがあります。
もう一つcdには地味だけど便利な特徴があります。
引数を指定せずに、単に cd
と打ち込むと、そのユーザーのホームディレクトリヘと戻ってきます。
root@freebsd:/usr/include/c++/v1 # cd⏎ root@freebsd:~ # pwd⏎ /root root@freebsd:~ # ▋
これもよく使うので覚えておいて損はないです。
6 まとめ
ここまでで、pwd、ls、cdと見てきました。 今の状態でFreeBSDのファイルシステム全体を探索してみることが可能となりました。
しかし、目的を忘れてはいません。 Hello Worldのプログラムを実行させることです。 プログラミングをするにはもう少しだけ知っておくべきコマンドがあります。 今のままでは、歩き回ってちらっと覗いてみることしかできません。 何かしら変更を加える方法を知る必要があります。 次回はそのコマンドを紹介します。