ふつうのLinuxプログラミング（の第1部だけ）を読んでいく

雑にまとめているのであとで書き直す。

# 第0部

- Linux の世界は3 つの概念によって成立している。
    - ファイルシステム
    - プロセス
    - ストリーム

# 第1部

Linuxの基本用語解説

## 第1章

- ある関数を使うためにどのヘッダファイルをインクルードすればよいか、ということはmanに書いてある。
- 「*」や「?」のようなファイル名展開機能（グロブ）はシェルの機能。
- argc
    - コマンドライン引数の数
- argv
    - コマンドライン引数の実体（charへのポインタの配列）
- man
    - リファレンスマニュアル。
        - printfにはコマンドのprintf(1)とライブラリ関数のprintf(3)があったりする。
- info 
    - ドキュメントシステム。
- ウェブ
    - man, info 以外のUNIXの情報源　※グーグル検索。

## 第2章

- Linxのソフトウェアパッケージ
    - シェル（bash, ash, csh, tcsh, zsh, pdksh, ...）
    - util-linux(init, getty, login, reset, fdisk, ...)
    - procps(ps, pstree, top, ...)
    - GNU coreutils(ls, cat, mkdir, rmkidr, cut, chmod, ...)
    - GNU grep, findutils, diffutils(grep, find, diff, ...)
    - GNU libc
    - 各種の基本ライブラリ(ncurses, zlib, GDBM, ...)
    - 開発環境(gcc, binutils, make, biscon, flex, ヘッダファイル類, ...)
    - X Window System
    - GNOMEやKDE

- Linux ディストリビューション
    - Red Hat, CentOS, Ubuntu, Debian, SUSE, Gento

- Linux は Unix 風OSの一種。

- macOSは大半がFreeBSDからの派生。

- カーネル
    - OSの核である。
    - 1つのプログラムで構成されている。
    - コンピュータを構成する全てのハードウェアとソフトウェアを管理している。

- ルートディレクトリにある vmlinuz, vmlinux, vmlinuz-XXX といった名前のファイルがLinuxカーネルのプログラム本体。
- 厳密には「Linux」という単語はカーネルを指す。
- デバイス
    - カーネルは、以下のような物理的なハードウェアを統括する。
        - CPU
        - メモリ
        - HDD（ハードディスクドライブ）
        - SSD（ソリッドステートドライブ）
        - DVD-ROMドライブ
        - CD-ROMドライブ
        - グラフィックアダプタ（画像モニタに送る部品）
        - ネットワークアダプタ
        - サウンドカード
        - 時計（ハードウェアロック）

- デバイスドライバ
    - 特定のデバイスを操作するためのソフトウェア部品のこと。

- システムコール
    - カーネルに仕事を頼む仕組み。
        - システム -> カーネル
    - 前提
        - ハードウェアと直接やり取りできるのはカーネルだけに（つまりデバイスドライバだけに）限定されているので、普通のプログラムがハードウェアを操作したいときはカーネルに仕事を頼んで間接的に操作するしかない。
            - カーネルはシステムで一番偉いプログラムだが、一方で一番下っ端にいてこき使われるプログラムでもある。
    - システムコールの呼び出しも見た目はごく普通の関数呼び出し。
        - 例
            - open, read, write, fork, exec, stat, unlink

- カーネルまとめ
    - Linux世界とは、Linuxカーネルの作り出す世界であり、そのカーネルに仕事をさせるにはシステムコールを使うしかない。
    - ファイルシステム・プロセス・ストリームについても、システムコールを通じてイメージを作り上げていく。

- ライブラリ関数
    - プログラミングするときに、システムコール以外にも使える関数。
        - 例: printf(), exit(), strlen(), strcpy(), ...
    - ライブラリ関数を *リンク(link)* すると、その関数を呼び出すことができるようになる。

- libc
    - 標準Cライブラリ(standard C library)
    - Ubuntuなら /lib, CentOSなら /lib64 ディレクトリの下に中核となるファイルがある。
    - GNU libc
        - Linuxで普通使われているlibc。
        - GNUプロダクトの一部なので、Linuxカーネル開発者のLinusさんではない別の人が作っている。

- API
    - 例えば、libxのAPIは関数やマクロ、カーネルのAPIはシステムコール。

## 第3章

### 3-1. ファイルシステム

- ファイル
    - 広義のファイル
        - ls で表示されるもの
            - 狭義のファイル
                - regular file
                    - 内容がそのまま記録されているファイル。
                        - テキストファイル、画像ファイル、動画ファイルなど。
            - ディレクトリ
                - 他のファイルを複数入れることができるファイル。
            - シンボリックリンク
                - 他のファイルの名前を格納したファイル。
                - 別名ソフトリンク(soft link)。
            - デバイスファイル
                - デバイス（ハードウェア）をファイルとして表現したもの。
                    - APIを使ってSSDやHDDに記録されているデータを操作できるが、非常に危険なので試してはいけない。
                - キャラクタデバイスファイル
                    - プリンタやモデム
                - ブロックデバイスファイル
                    - SSDやHDD
            - 名前付きパイプ
                - プロセス間通信に使うファイル。FIFO。
                - 使用頻度は低い。
            - UNIXドメインソケット
                - プロセスかん通信に使うファイル。
                - 現在ではTCPソケットで代替できる。

- ls -l コマンド
    - ファイルの付帯情報を表示できる。
        - ファイルの種類
        - パーミッション
        - サイズ
        - 更新時刻

#### まとめ

- 何らかのデータを保持する
- 付帯情報がついている
- 名前（パス）で指定できる

- ファイルシステムはSSDやHDD、USBメモリのような、物理的な記憶媒体の上にある。
    - パーティション
        - ディスクの区画の区切り。
    - マウント
        - パーティションの上にファイルシステムを用意して、一本の巨大なディレクトリツリーを作る。

### 3-2. プロセス

- プロセス
    - 動作中のプログラムのこと。
    - 1つのプログラムがあればプロセスはいくつでも作れる。
- プログラム
    - ファイルのような形態で存在しているデータのことも含む言葉。

- プロセスID
    - psコマンドの出力の左から2番目の欄の番号。
    - プロセスを一意に指定する。
- シグナル
    - Ctrl + C を押してプロセスを止める仕組みを支えている。
        - カーネルが該当プロセスに割り込みシグナルを送り、それを受け取ったプロセスは自発的に終了する。
    - UNIXに古くからある仕組みで、UNIX(Linux)プログラミングでは非常に重要な位置を占める。

### 3-3. ストリーム

- ストリーム
    - バイトの流れのことを指す。バイト列が流れる通り道。
    - 他書では「ファイル」や「open file」と呼ばれている。
    - FILE型の値
        - FILE型
            - ストリームを操作するときに使うデータ構造。
    - STREAMSカーネルモジュール
        - STREAMS
            - ストリームを提供するために使われるカーネルモジュール
- ストリームが使用されている例 1
    - プロセスがファイルの内容にアクセスしたいとき。
        1. ファイルにつながるストリームを作ってもらえるようにカーネルに（システムコールを使って）頼む。
        2. そしてまたシステムコールを使い、ストリームを操作してファイルの中身を取り出す。
- read
    - ストリームからバイト列を取り出すこと
    - ファイルの内容を読む
- write
    - ストリームからバイト列を流し込むこと
    - ファイルに書く

- ストリームが使用されている例 2
  - キーボードのキーの押下。
    - 押下されたキーを表すバイトの列を送りつけてくるストリームだと考えられる。

- デバイスファイルは、ストリームを得るためのとっかかりとして存在する。

- パイプ
    - プロセスが両端にいるストリーム
    - less コマンドや grep コマンドを使うときのパイプ
    - パイプの仕組み
        1. まず各コマンドを独立したプロセスとして同時に実行する。
        2. そのプロセス間をストリーム（パイプ）で繋ぐ。

- ネットワーク通信
    - ストリームが別のコンピュータまで延びていること。
        - 一方のコンピュータのプロセスから、もう一方のコンピュータのプロセスに繋ぐ。
        - バイト列がちゃんと輸送される限り問題ない。

- プロセス間通信
    - パイプやネットワーク通信のように、プロセス同士がストリームを通じてデータをやりとりしたり意思の疎通を図ること。
    - ストリーム以外を使ったプロセス間通信機構もある。
        - POSIX IPC

### まとめ

- ファイルシステム
    - データに名前をつけて保存する場所
- プロセス
    - 何らかの活動をする主体
- ストリーム
    - プロセスがファイルシステムや他のプロセスとデータをやり取りする手段

- これだけで、Linux OSの構造はおおむね語ることができてしまう。

## 第4章

### 4-1. ユーザーとグループ

- login
    - Linuxを使うとき、まず最初にユーザー名とパスワードを入力する。
        - 自分専用のホームディレクトリに移動し、自分用のシェル（bash）が起動して、自分に許可されているファイルを読み書きできるようになる。

- マルチユーザーシステム
    - Linuxのように複数のユーザーが同時に使えるシステムのこと。
    - UNIXがそうだった。
    - システムにとって重要なファイルは普段使うユーザーとは別のユーザーの所有にしておき、所有者以外には変更できないようにすることで、重要なファイルをうっかり消してしまうことがなくなる。

- スーパーユーザー
    - root
    - あらゆるファイルを変更、削除、プロセスを停止できる権限を持っている。

- グループ
    - ユーザーのグループ。
    - グループに権限を与えるとそのグループのメンバ全員に権限を与えたことになる。
        - 特定のデバイスファイルの使用許可。
    - 各ユーザーは常に最低1つのグループに所属している。
        - useraddコマンドでユーザーを作成するなら、-gオプションでグループを指定できる。

- パーミッション
    - 3つのユーザー区分と3つの権限がある。
    -  ファイルにはそれを所有するユーザーとグループが決まっている。
        -  ファイルを所有するユーザー
        -  ファイルを所有するグループに所属するユーザー
        -  それ以外のユーザー
    -  権限の種類
        -  読み込み（read, r）
        -  書き込み(write, w)
        -  実行(execute, x)
    -  例:
        -  rw-r--r--
            -  所有者読み書き可能、所有グループ読み込み可能、その他のユーザ読み込み可能。
            -  普通のファイル。
        -  rwxr-xr-x
            -  所有者読み書き実行可能、所有グループ読み込み実行可能、その他のユーザ読み込み実行可能。
            -  プログラムやディレクトリ。
        -  rw-------
            -  所有者のみ読み書き可能。
            -  SSHの秘密鍵など、本人以外に見られてはまずいファイル。

- パーミッションの8進表記
    - 例：
        - rwxr-xr-x
            - rwx=4+2+1, r-x=4+0+1, r-x=4+0+1 = 755
        - rw-r--r--
            - 644

- ディレクトリのパーミッション
    - 読み込み可能の場合
        - その中のファイル一覧を得られる
            - lsコマンドなど
    - 書き込み可能の場合
        - その中に新しいファイルを作成したり削除できる
    - 実行可能の場合
        - そのディレクトリ中のファイルにアクセス（読み書き実行）できる

- クレデンシャル
    - プロセスの属性としてのユーザーのこと
        - 「ユーザーAとして操作する」=「ユーザーAの属性を持ったプロセス群を操作する」
    - 「このプロセスはLinux上においてこのユーザーの代理人として動作しているぞ」という証明書のこと。
        - カーネルはその証明書を見てパーミッションを判断する。
        - ログイン（login）の過程で、証明書を持つプロセスがシステム上に作成される。

- ユーザー名とユーザーID
    - カーネルはユーザー名に対応するユーザーIDのみを扱う。

- ユーザーデータベース
    - ユーザー名とユーザーIDの対応が書いてあるファイル。
        - 一般的には /etc/password にある。
        - 例:
            - root:\x:0:0:root:/root/:/bin/bash
                - ユーザー root, パスワード x, ユーザーID 0, ユーザーグループ 1

### 4-2. シェルと端末

- コマンドラインとは、以下の2つからなる。
    1. シェル（shell）
    2. 端末（terminal）

- 端末
    - コンピュータのハードウェアのうち、人が直接に接する部分。

- 端末の歴史
    - テレタイプ
        - UNIXの黎明期に大量に使われていた端末。
        - ディスプレイがなかった時代の、コンピュータからのプリンタ出力やタイプライター入力。
            - テレタイプに由来して、UNIXでは端末のことを *tty* と呼ぶことがある。
    - ダム端末
        - テレタイプの後に登場した端末。
        - 文字だけを表示可能なディスプレイと、キーボードと、それに付随するハードウェア。
    - キャラクタ端末
        - 初期のダム端末。
        - ディスプレイに文字しか表示することができない。
    - ビットマップディスプレイ
        - 細かい色の点の集まりで全てを表現する。
    - X端末
        - X Window Systemを動作させるために使われた、ビットマップディスプレイを装備した機種。
    - 端末エミュレータ
        - 元々ハードウェアであった端末を全てソフトウェアにしてしまったもの。
            - macOSのTerminal.appやiTerm2など。
        - 現代的なビットマップディスプレイを持った端末であるパソコンの中で、あえてキャラクタ入出力を行う、最先端のような先祖返りのような端末。

- 仮想コンソール
    - Linuxでは物理的な端末がそのまま使われるわけではなく、仮想コンソールというものが間に挟まっている。
        - ソフトウェア的な端末。

- キャラクタ端末とASCII
    - 現代的なGUIを備えたコンピュータで「a」を表示するときは、あらかじめメモリ上に「a」を表現する画像を作っておき、「このような画像を表示せよ」と命令する。
    - ASCII
        - 文字コード。
        - 端末に「aという文字を表示しろ」と指定するとき、文字と数値を対応づけて、その数値を伝える。

- ファイルとしての端末、ストリームとしての端末
    - ファイルとして表現されていると、表現されているものに接続するためのストリームが得られる。
        - 端末につながったストリームを読むとキーボードからの入力が得られ、端末につながったストリームに書くとディスプレイに文字を出力できる。

- シェル
    - ユーザーからの命令を解釈して実行するプログラムのこと。
        - sh, bash, csh, tcsh, zsh, ksh, ash
    - シェルはログイン時に起動されるという点で少し特別なだけで、それ自体はストリームからコマンドを読み込んで実行するプログラムに過ぎない。
        - そのストリームが端末につながっている場合、「$」や「%」のようなコマンドラインプロンプトを出力する。