基本的なUNIXコマンド

目次

Unknown programmer's programming note.

<2021-12-30 木>

1 概要

前回は、FreeBSDにログインしてシャットダウンするコマンドを紹介しました。 それだけでは起動してすぐ終了する以外にできることがありません。 今回は、ファイルとディレクトリに関するコマンドを扱います。 取り扱うのはごく基本的なものだけです。

先にどのようなもの扱うか示してしまいます。

  • ls
  • cd
  • pwd
  • mkdir
  • rmdir
  • cat
  • cp
  • mv
  • rm

まずはこれだけです。これだけ覚えれば最初の目標のHello Worldのプログラムを実行させるのに十分です。

2 UNIXのファイルシステムについて

コマンドの説明に入る前に、UNIXのファイルシステムについて触れておきます。 ファイルシステムと言うと、SSDやハードディスクをフォーマットした経験のある人は、FAT32とかNTFSといったフォーマットの形式のことを想像されるかもしれません。 ここで話そうとしているのはそのフォーマットの形式のことではありません(まったく無関係なわけでもありませんが、扱いません)。 UNIXがシステムの情報や設定やプログラムをどのように保持しているのか、そしてユーザーが作成したものをどのように保持するのかについてです。 UNIXはそういったものをツリー構造(木構造)に構造化して管理しています。

といっても言葉では伝わりづらく、絵で見た方が理解しやすいと思い作成しました。

UNIX file system t

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/file1ls -l projects/program1/file2 のように長々と指定しなければなりません。 これよりは ls -l file1ls -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のプログラムを実行させることです。 プログラミングをするにはもう少しだけ知っておくべきコマンドがあります。 今のままでは、歩き回ってちらっと覗いてみることしかできません。 何かしら変更を加える方法を知る必要があります。 次回はそのコマンドを紹介します。

著者: watercat

Created: 2023-03-19 日 01:34

Emacs 27.1 (Org mode 9.3)

Validate