Linuxコマンドのソースコードを取得する方法：オリジナルコマンド作成前の勉強向け

# 追記
以下の情報では、不足があったため、[自サイト(debimate.jp)](https://debimate.jp/2019/06/01/linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95debian%E7%92%B0%E5%A2%83/)に加筆版をUPしています。

#前置き
[CQ出版社のInterface誌（2016年10月号）](http://www.kumikomi.net/interface/contents/201610.php)に、「レベルアップ！ オリジナル・コマンドを
作る」という記事がありました。
この記事中では、C言語(高速な言語)による自作コマンドの作成について、少しだけ触れられていました。
残念な事に、C言語による具体的な作成方法が記載されていませんでした。
この理由には、「紙面の文字数制限」、「bashの特集記事であった事」が考えられます。

C言語で自作コマンドを作成する上で、以下の2点が必要な情報ではないかと考え、
私は、ついカッとなって、本記事を作りました(ついでに、Interface誌にもアンケートを出しました)。
　・自作コマンド作成時の参考(既存コマンドのソースコード)の取得方法
　・自作コマンド(実行形式ファイル)の格納先

ちなみに、[「lsを読まずにプログラマを名乗るな！(秀和システム)」](http://www.shuwasystem.co.jp/products/7980html/3943.html)なんて恐ろしい書籍もありますし、
コマンド(パッケージ)のソースコード取得は、プログラマなら覚えておいて損はないと思います。

#検証環境
　・iMac(OS X El Capitan 10.11.4)
　・VirtualBox(5.0.26 r108824)
　・Debian8.5(64bit)

※本記事では、CUI/GUIでのソースコードの取得方法を取り上げます。
　GUIの場合は上記の環境にこだわる必要はありません。

#一般的なコマンドの格納先
Linuxのコマンドの格納先は、以下のディレクトリです。
自作コマンドの格納が推奨されているディレクトリは、/usr/local/bin です。

|dir                 | 役割                                             |
|:-------------------|:------------------------------------------------|
|/bin                |一般的なコマンド格納先（cat、rmなど）                   |
|/usr/bin            |一般ユーザ向けコマンド格納先（make、wgetなど）          |
|/usr/sbin           |管理者向けコマンド格納先(chroot、useraddなど)        |
|/usr/local/bin      |評価版パッケージや自作コマンドの格納先                |


特定のコマンドの格納先が知りたい場合は、下記のコマンドでパスを取得できます。

| コマンド名 | 機能 |
|:--|:--|
| [whereis](http://itpro.nikkeibp.co.jp/article/COLUMN/20140212/536211/) | コマンド格納先、manの格納先を表示する。  |
| [which](http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/230996/?rt=nocnt)  | コマンドの格納先を表示する。  |

#コマンドのソースコードの取得方法(CUI)
まず、コマンドが提供されるパッケージ名を調査します。
今回は、mkdirコマンドを例にします。

```
$ sudo apt-get install dpkg-dev  # この手順は不要な環境が存在します。
$ which mkdir                    # mkdir格納先(絶対パス)を取得。
  /bin/mkdir
$ dpkg --search /bin/mkdir
  coreutils: /bin/mkdir
```

上記のdpkgコマンドにより、mkdirはcoreutilsパッケージで提供される事が分かりました。
なお、apt-fileコマンドを用いて、パッケージ名を取得する方法もあります。
ただし、こちらの方法は、複数のパッケージ名や関係のないディレクトリも表示されます。


```
$ sudo apt-get install apt-file  # この手順は不要な環境が存在します。
$ apt-file update                # データベースの更新。
$ which mkdir                    # mkdir格納先(絶対パス)を取得。
  /bin/mkdir
$ apt-file search /bin/mkdir     # grepコマンド(パイプ)で取捨選択した方が好ましい。
  9base: /usr/lib/plan9/bin/mkdir
  coreutils: /bin/mkdir
  klibc-utils: /usr/lib/klibc/bin/mkdir
  xutils-dev: /usr/bin/mkdirhier
```

では、最後にapt-getコマンドで該当パッケージをソースコード形式で取得します。
ソースと同時に、パッチやdscファイルが付いてきますが、
これらはDebian環境下のパッケージ管理に関わる内容なので、今回は無視します。
(パッチは当てた方が良いですが……)

```
$ apt-get source coreutils
$ ls
  coreutils-8.23  coreutils_8.23-4.diff.gz
  coreutils_8.23-4.dsc  coreutils_8.23.orig.tar.gz
$ cd coreutils-8.23/src         # coreutils-8.23以下のファイルは、Debianの流儀に沿った内容となります。
$ ls | grep mkdir               # mkdir以外のコマンド(ソースコード)が格納されているため、grepを使用。
  mkdir.c
```

ちなみに、mkdir.cの行数は約300行でした(コメント含む)。
この程度の規模であれば、大学生でも簡単に読めると思います(関数ポインタがありますが)。


#コマンドのソースコードの取得方法(GUI)
一例ですが、以下のサイトからパッケージ名を検索して、ソースを取得する事ができます。

　・[Debian公式サイト](https://packages.debian.org/jessie/coreutils)
　・[Ubuntu公式サイト](http://packages.ubuntu.com/ja/)
　・[GNUオペレーティング・システム](https://www.gnu.org/)

#最後に
mkdirのソースを読みながら、「C言語で自作コマンドを作成するメリット(速度以外)」を考えました。
まず、UNIX哲学に則れば、一つの事を上手くやるコードを書かなければいけません。
しかし、[Linuxが25周年を迎えた現在](http://gihyo.jp/admin/clip/01/linux_dt/201608/25)、下手にコマンドを自作するより、
OSSに存在するパッケージを活用した方が早い気がします。
そもそも、システムコールに精通していなければ、コマンドを作成するのは難しいと考えられます。
(システムコールに関しては、[「Linuxプログラミングインターフェース」](https://www.oreilly.co.jp/books/9784873115856/)が名著です。)

そう考えると、C言語でコマンドを作成するメリットに関する掘り下げが、Interface誌で欲しかったです。
でも、特集としてはbash(シェルスクリプト)でしたし、雑誌に多くの情報を求めるのは酷か。