LPIC 1 対策メモ①

## 1.システムアーキテクチャ

- 基本的なシステムハードウェア
	- CPU
	- メモリ
	- HD
	- 入力装置
	- 拡張カード
	- USB 機器

- BIOS / UFEI
	- デバイスを制御する最も基本的なプログラム
	- マザーボード上の BIOS：システム BIOS ⇔ 拡張 BIOS
	- 周辺機器のオン・オフ、起動ドライブの順序設定などを行える

- /proc 以下のファイルによりカーネルが認識しているデバイスを確認できる
	- /proc/cpuinfo：CPU 情報
	- /proc/bus/usb/\*：USB デバイス情報  
	など

- /dev 以下にはデバイスファイル（ハードウェアのアクセスを抽象化）がある
	- udev という仕組みで自動的に作成

- デバイス情報を表示する各種コマンド：
	- `$ lspci`：PCI デバイス情報
		- `-v` や `-vv` で詳細な情報

- USB はホットプラグデバイス
	- `$ lsusb`：USB デバイスの情報表示

- デバイスドライバ：デバイスを利用するために必要な制御プログラム
	- `$ lsmod`：ロードされているカーネルモジュールを確認
		- `$ cat /proc/modules` でも確認できる
	- `$ modprobe` コマンドでデバイスドライバをロードできる

- システム起動の流れ
	- BIOS/UFEI
		- ハードウェアのチェックや初期化
	- ブートローダ
		- カーネルをメモリ上へ読み出す
	- カーネル
		- メモリの初期化、ルートファイルシステムのマウントなど
	- init / systemd
		- 必要なサービスを順次起動

- `$ dmesg`：起動時にカーネルが出力するメッセージを確認
	- 長時間起動してると起動時のメッセージは消えうる

- `$ shutdown` コマンドでシステムの停止や再起動を行う
	- `$ shutdown -h +5 "Please logout immediatly."`：5分後にシャットダウン
	- `-k`：警告だけ
	- `-r`：再起動

- Linux が起動するまで
	- SysVinit：古い
	- systemd：主流

- SysVinit を採用したシステムでは、/etc/inittab でデフォルトのランレベルを設定できる
	- `# runlevel` で前と現在のユーザレベルを表示
	- `# init`、`# telinit`：ランレベルの変更

|ランレベル|説明|
|:-:|:-:|
|0|停止|
|1|シングルユーザーモード|
|2|マルチユーザーモード（テキストログイン）|
|3|マルチユーザーモード（テキストログイン）|
|4|未使用|
|5|マルチユーザーモード（グラフィカルログイン）|
|6|再起動|
|S/s|シングルユーザーモード|


- sysytemd を採用したシステムでは、`# systemctl` コマンドでサービスを管理する
	- `# systemctl start/stop/restart/status postfix.service` など
	- `# systemctl enable postfix.service`：起動時に自動起動させる




## 2.Linux のインストールとパッケージ管理

- Linux のインストールには、少なくともルートパーティション（/）とスワップ領域が必要

- /var や /home は / とは別のパーティションを準備して利用すべき  
肥大化しやすいため

- スワップ領域は物理メモリと同程度か２倍くらい  
物理メモリ不足時に仮想メモリとして利用

- ブートローダ：HD などのストレージから OS を読み込んで起動
	- GRUB：代表的なブートローダ  

- `# grub-install /dev/sda`：GRUB /dev/sda の MBR にインストール

- GRUB Legacy の設定ファイルは /boot/grub/menu.lst

- GRUB 2 は /etc/default/grub で設定を行い、`# grub-mkconfig` を実行することで、設定ファイル /boot/grub/grub.cfg を生成する

- ブートローダ起動時、「A」または「E」入力で、ブートオプションを指定できる

- ライブラリ
	- スタティックリンク
		- コンパイルで埋め込まれる
	- ダイナミックリンク
		- 実行時にライブラリを呼び出す
		- 呼び出されるライブラリを共有ライブラリという

- 実行ファイルが必要とする共有ライブラリは `$ ldd` で調べる
	- `$ ldd /bin/cat`

- 共有ライブラリは `ld.so` によってリンクされる
	- `ld.so` が参照する `/etc/ld.so.cache` は、`/etc/ld.so.conf` をもとに `$ ldconfig`で作成される

- Debian パッケージの管理
	- `# dpkg`  
		- `-i/--install <pkg file name>`：インストール
		- `-r/--remove <pkg>`：設定ファイルを残してアンインストール
		- `-P/--purge <pkg>`：設定ファイルも含め完全にアンインストール
		- `-S/--search <file>`：指定したファイルがどのパッケージからインストールされたか
		- `-l/--list`：インストール済みパッケージ一覧表示
	- APT ツール
		- `# apt-get`
			- `update`：パッケージの最新情報を取得
			- `install/remove <pkg>`
			- `dist-upgrade`：システムを一括して新しいバージョンにアップグレード
			- `upgrade`：削除を伴わないアップグレードのみ
		- `$ apt-cache`：パッケージ情報を照会・検索
			- `search <keyword>`：keyword を含むパッケージを検索
			- `show <pkg>`：情報表示
			- `depends <pgk>`：依存関係情報表示
		- `# aptitude`：`apt-get` よりも高機能
			- install, remove, purge, search, show
	- APT の設定ファイルは `/etc/apt/sources.list`  
	パッケージを管理しているサイトの URL を記述

- RPM パッケージの管理（RedHat系）
	- `# rpm`
		- `-i/--install <pkg file name>`
			- `-ivh`：詳細情報(-v)・進行状況表示(-h)
			- `--nodeps`：依存関係無視
		- `-U/--upgrade <pkg file name>`：アップグレード（なければインストール）
		- `-F/--freshen <pkg file name>`：アップグレード（なければ無視）
		- `-e <pkg>`：アンインストール
			- `--nodeps` 依存関係無視
		- `-q <pkg>`：インストールされているか照会する
			- `-qa`：インストール済みのパッケージを全て表示
			- `-ql <pkg>`：パッケージからインストールされたファイルをすべて表示
			- `-qc <pkg>`：パッケージからインストールされた設定ファイルのみ表示（config）
			- `-qd <pkg>`：パッケージからインストールされたドキュメントファイルのみ表示（document）
			- `-qf <file>`：ファイルがどのパッケージからインストールされたか表示
			- `-qR <pkg>`：パッケージが依存しているファイルなどを表示
	- `# yum`：APTツール に相当
		- `check-update`：アップデートされるパッケージを確認
		- `update`：インストール済みのパッケージをすべてアップデート
		- `update <pkg>`：特定のパッケージ
		- `install/remove <pkg>`
	- YUM リポジトリの設定は /etc/yum.repos.d ディレクトリ以下のファイルで行う

- (memo)
	- option で指定するのはプリミティブな dpkg や rpm
	- apt-get の update と yum の update の違いに注意

## 3.GNU & UNIX コマンド
- 変数

```sh
$ VAR=lpic # シェル変数セット # 定義のときは $ 不要
$ echo $VAR # 展開したいときだけ $ をつける
lpic
$ bash
$ echo $VAR
# VAR は 未定義になる
$ exit
$ export VAR
$ bash
$ echo $VAR
lpic # export すれば環境変数になる
$ exit
$ unset VAR # 削除
```

- 環境変数

```sh
$ env # 環境変数一覧
$ printenv # 環境変数一覧
$ set #  環境変数・シェル変数一覧
```

- `PATH`：コマンド検索パス（環境変数）
	- `PATH=$PATH:/path/to/dir`

- 複数コマンドの実行

```sh
$ cmd1; cmd2 # 連続実行
$ cmd1 && cmd2 # cmd1が成功したときのみ
$ cmd1 || cmd2 # cmd1が失敗したときのみ
```

- 文字列

```sh
$ DATE=date
$ echo $DATE # 単純に展開
date
$ echo '$DATE'
$DATE # 完全な文字列
$ echo "$DATE"
date # 展開される
$ echo `$DATE`
Sun Feb 8 12:42:18 JST 2015 # コマンドと解釈され展開
```

- `$ history`：コマンド履歴
	- .bash_history に保存
		- HISTFILE で指定
	- `$ !5`：履歴番号5を実行
	- HISTSIZE、HISTFILESIZE：履歴を残す数を指定する環境変数

- `$ man`：オンラインマニュアル表示
	- `$ man 5 passwd`：passwd コマンドではなく /etc/passwd フィアルのフォーマットに関するマニュアル表示
	- 主なセクション：

|セクション|説明|
|:-:|:-:|
|1|ユーザーコマンド|
|5|ファイルフォーマット|
|8|システム管理コマンド|

- `$ ls`
	- `-a`：隠しファイルも表示
	- `-l`：詳細情報表示
	- `-d`：ディレクトリ自身の情報表示

- `$ cp`
	- `-r`：ディレクトリを再帰的にコピー
	- `-p`：ファイルの属性を維持してコピー

- `$ mv`
	- `-f`：同名があれば上書き

- `$ mkdir`
	- `-p`：親ディレクトリも一気に作成

- `$ rm`
	- `-r/-R`：再帰的にディレクトリ消去
	- `$ rmdir`：空のディレクトリを削除

- `$ touch`
	- `touch -t 201502012030 sample`：タイムスタンプ変更
	- `-a`：アクセス時刻だけ変更
	- ファイルが存在しない場合、空のファイル作成

- `$ file`：ファイルの種別を確認

- `$ ls *.txt`
	- シェルによって展開される
	- ls が * を解釈しているのでは無いことに注意
	- 正規表現とは別、* はただの「任意の文字（列）」
	- file[123].txt なども使える

- パイプ

``` sh
$ dmesg | less # 出力を入力として渡す
$ ls -l | tee ls_log | wc -l # ls の出力を ls_log に書き出した上で、出力を wc に渡せる（分岐させる）
```

- リダイレクト

``` sh
$ ls -l > filelist # 上書き
$ ls -l >> filelist # 追記
$ grep "lpic" < target.txt > result.txt # 標準入力を target.txt に変更
$ cat > sample.txt << EOF # ヒアドキュメント。特定の文字列が現れるまで入力を続ける
> LPI
> Linux
> EOF # 短いファイルならエディタを使わずに作成できる
$ find / -name "*.tmp" 2> error.log # 標準エラー出力をリダイレクト
$ find / -name "*.tmp" > find.log 2>&1 # 標準エラー出力を標準出力先に合わせる（即ち、find.log）
$ find / -name "*.tmp" 2>&1 # 標準エラー出力を標準出力先に合わせる（即ち、端末画面）
$ find / -name "*.tmp" &> find.log # 標準出力・標準エラー出力まとめてリダイレクト
$ find / -name "*.tmp" > /dev/null # /dev/null は書き込まれたデータがすべて消える特殊ファイル
```

- `$ cat`
	- `$ cat file1 file2 > newfile`：複数のファイルを結合

- `$ nl <file>`：行番号をつけてファイルを表示

- `$ od <file>`：バイナリファイルを8/16進数表示
	`-o`：8進数（デフォルト）
	`-x`：16進数

- `$ head/tail -n <行数> <file>`

- `$ cut`
	- `-c 5 <file>`：各行の5文字目を表示
	- `-d: -f 6 /etc/passwd`：デリミタを指定（ここでは「:」、デフォルトはタブ）、第6フィールド取り出し

- `$ join -j 1 sample1.txt sample2.txt`：第1フィールドが共通な行を連結

- `$ paste -d";" sample1.txt sample2.txt`：水平方向に連結する

- `$ tr`：文字列の置換
	- `$ cat /etc/hosts | tr 'a-z' 'A-Z'`：大文字へ変換
	- `$ cat /etc/hosts | tr [:lower:] [:upper:]`：クラスも使える

- `$ sort`：行をソートする

- `$ split -100 sample.txt s_sample.`：ファイル分割
	- s_sample.aa s_sample.ab ... と分割される

- `$ uniq <file>`：重複した行をまとめる
	- `$ sort file1 | uniq`：先にソートしておく必要がある

- `$ pr`：印刷前などにファイルの整形

- `$ fmt`：テキストを決められた桁に整形

- `$ expand <file>`：タブをスペースに変換
	- `$ unexpand <file>`：行頭にある連続した空白をタブに変換

- `$ wc <file>`：行数（-l）・単語数（-w）・文字数（-c）をカウント

- `$ xargs`：標準入力から受け取った文字列を引数に指定して、与えられたコマンドを実行
	- `$ echo * | xargs rm`：シェルの制限を超える時に、制限を超えないよう適切に処理してくれる

- `$ grep`
	- 正規表現が使える
	- `$ grep -v ^# httpd.conf`：-v で否定の意。# が入ってない行のみ抽出

- `$ sed`

``` sh
$ sed s/linux/LINUX/ file1.txt # s/検索パターン/置換パターン/
red hat LINUX
vine LINUX
LINUX linux linux
$ sed s/linux/LINUX/ file1.txt # g をつけると１行にパターンが複数あったらすべて置換
red hat LINUX
vine LINUX
LINUX LINUX LINUX
```

- vi エディタ
	- コマンドの前に数字を入力すると、回数分行われる
		- `8dd`：5行削除
	- `ZZ` = `:wq`
	- `/lpic`：後方へのキーワード検索
	- `?lpic`：前方へのキーワード検索

## 4.ファイルとプロセス管理

- ファイルの圧縮・解凍
	- `$ gzip <file>`
		- `-d`：解凍
			- `$ gunzip` と同じ
		- `-r`：ディレクトリ内のファイルをそれぞれ圧縮
		- `-c`：標準出力へ出力（もとのファイルを残したいとき）
	- `$ bzip2 <file>`：圧縮率高
		- `$bzip2 -d <file>` = `$ bunzip2 <file>`
	- `$ xz`：さらに圧縮率高
		- `$xz -d <file>` = `$unxz <file>`

- アーカイブの作成
	- `$ tar cvf /dev/st0/ /home`：/home のアーカイブを /dev/st0 に作成（非圧縮）
		- c：アーカイブ作成、x：アーカイブからファイル取り出し
		- v：詳細表示
		- f：アーカイブファイル名指定
		- z：gzip による 圧縮/展開、j：bzip2 による 圧縮/展開
	- `$ ls | cpio -o > /tmp/backup`：アーカイブ作成
		- 標準入力からファイル名を受け取る

- `# dd if=/dev/sdb of=/dev/sdc`
	- cp はファイルをコピーするだけだが、デバイスからデバイスへコピーできる

- アクセス権
	- -rwxr-xr--：所有者、グループ、その他のユーザ、の順

``` sh
$ chmod go+w samplefile # u：user、g：group、o：others
$ chmod o-rw samplefile
$ chmod 644 samplefile
```

- SUID や SGID が適用されたプログラムは、実行ユーザによらず、ファイルの所有者もしくは所有グループの権限で実行できる
	- `$ passwd` が誰でも実行できるのはこのため
	- `# chmod u+s samplefile`：所有者の実行権に s を設定すると SUID（4000 を足す）
	- `# chmod g+s samplefile`：グループの実行権に s を設定すると SGID（2000 を足す）

- スティッキービットを設定したディレクトリでは、自分が所有するファイル以外は削除できない
	- `# chmod o+t sampledir`：others の実行権に t を設定する（1000 を足す）

- ファイルやディレクトリのデフォルトのアクセス権は umask 値で決まる
	- `$ umask` で確認
	- `$ umask 027` で設定
	- ファイルは 666 から、ディレクトリは 777 から umask 値を引いた値がデフォルト

- `$ chown user1 testfile`：所有者変更
	- `-R`：指定したディレクトリと、その中のファイル全て変更
	- `chown user1:group1 testfile`：同時にグループも変えられる
- `$ chgrp grp1 testfile`：グループ変更
	- `-R`：指定したディレクトリと、その中のファイル全て変更

- リンク
	- ハードリンク：i ノードが同じ
		- `$ ln file.original file.link_hard`
		- ディレクトリのハードリンクは作成不可
		- 別ファイルシステム上に作成不可
	- シンボリックリンク：ポインタ
		- `$ ln -s file.original file.link_sym`：-s でシンボリックに
		- ディレクトリも可能
		- ファイルシステムが別でも可能
		- シンボリックリンク自体をコピーしたいときは `$ cp -d`

- `$ ps`：プロセス表示
	- `a`：他のユーザのプロセスも表示（デフォルトは自分のみ）
	- `x`：制御端末のないデーモンなどのプロセスも表示
	- `u`：ユーザ名も表示

- `$ top`：実行中のプロセスを継続的に監視

- `$ pstree`：親プロセス・子プロセスの関係まで表示

- PID：プロセスID
	- init の PID は常に 1
	- `$ pgrep vim` で簡単に PID を調べられる
	- `$ pgrep -u student`：ユーザ student のプロセスの PID 一覧表示

- kill

``` sh
$ kill -[signal name / signal ID] <PID>
$ kill -s [signal name / signal ID] <PID>
$ killall vim # PID ではなくプロセス名で指定できる、vim というプロセス名すべて
$ pkill -u lpic vim # lpic というユーザが実行している vim プロセスを kill
```

- 主なシグナル

|シグナル名|シグナルID|動作|
|:-:|:-:|:-:|
|HUP|1|ハングアップ|
|INT|2|割り込み（ctrl + c）|
|KILL|9|強制終了|
|TERM|15|終了（デフォルト）|
|CONT|18|停止しているプロセスを再開|
|STOP|19|一時停止|

- ジョブ：ユーザがコマンドやプログラムをシェル上で実行するひとまとまりの処理単位
	- `# updatedb &`：バックグラウンド実行
	- `# jobs`：一覧表示
	- `# nohup updatedb &`：ログアウトしてもプロセス実行

- フォアグラウンドとバックグラウンド

``` sh
$ tail -f /var/log/messages # ここで ctrl + Z を入力し、一時停止
$ bg 1 # ジョブ番号を引数にして bg へ

$ jobs # ジョブ番号を確認
$ fg 2 # ジョブ番号を引数にして fg へ
```

- システムの状況把握
	- `$ free`：メモリの使用状況、空き状況
	- `$ uptime`：システムの稼働時間や平均負荷
	- `$ uname`：システムのアーキテクチャや OS を確認

- `$ screen`：仮想端末を作成し、切り替えながら作業できる

- ナイス値：実行優先度
	- -20 ~ 19
		- 低いほど優先度が高い
		- 負数が設定できるのは root のみ
	- `# nice -n -10 updatedb`：優先度を -10 にして実行
	- `# renice -10 -p 1200`：実行中のプロセスの優先度を変えるときは renice


## 5.デバイスと Linux ファイルシステム

- ハードディスクの接続形態
	- SATA：主流
	- SAS：高価
	- SCSI：周辺機器
	- USB：外付け

- デバイスファイル
	- /dev/sd[abcd]：ハードディスク
	- /dev/sr0：CD/DVD ドライブ
	- /dev/st0：テープドライブ

- BIOS パーティション
	- 基本パーティション
		- 最大４個
	- 拡張パーティション
		- 基本パーティションの１つを拡張に出来る
	- 論理パーティション
		- 拡張の中に作成（/dev/sda5~）

- パーティションの作成
	- `# fdisk`：MBR
	- `# gdisk`：GPT
	- `# parted`：両方に対応

- ファイルシステムの作成
	- `# mkfs -t ext4 /dev/sdb1`
	- `# mke2fs`：ext2~4 ではこれも使える
		- `-t ext[234]`：ファイルシステムの種類指定
		- `-j`：ext3 を指定
			`# mkfs.ext3` と同じ
	- `# mkswap /dev/sda6`：スワップ領域を作成

- `$ df`：ファイルシステムの利用状況を確認
	- `-h`：適切な単位で

- `$ du`：ファイルやディレクトリが占めている容量を表示
	- `-a`：ファイルも表示

- ファイルシステムのチェック
	- `$ fsck`：ファイルシステムのチェック
		`$ fsck -t ext3` = `$ fsck.ext3`
	- `$ e2fsck`：ext2~4 ではこれも使える

- `$ tune2fs`：ext2~4 ファイルシステムのパラメータを設定

- `$ dumpe2fs`：ファイルシステムの各種情報を表示

- `$ mkfs.xfs`：XFS ファイルシステムを作成

- /etc/fstab：ファイルシステムの情報
	- /dev/sda1 /boot ext3 defaults 1 2
		- /dev/sda1：デバイスファイル
		- /boot：マウントポイント
		- マウントポイントが後

- マウント
	- `$ mount`：マウント情報表示
		`$ mount -a`：/etc/fstab に記述されたファイルシステムをすべてマウント
	- 	`$ mount -t ext4 /dev/sdb3 /data`
			- デバイス名またはマウントポイントを省略すると /etc/fstab が参照される
	- `$ umount /data`
		- マウントされているファイルシステムの情報は /etc/mtab に記述されている

- ディスククォータの管理
	- ハードリミット
	- ソフトリミット
	- 猶予期間
	- `$ quota`：ディスクの使用量とクォータの状況を表示
		- quota：ソフトリミット
		- limit：ハードリミット
		- grace：残り猶予期間
	- `$ quotacheck`：ファイルシステムを調べてディスクの使用量をチェック
	- `$ quotaon/off`
	- `$ edquota`：quota の設定
	- `$ repquota`：指定したファイルシステムのクォータ状況を表示

- FHS（Filesystem Hierarchy Standard）：標準化されたファイルシステム
	- /bin：基本的なコマンド
		- cat、ls、...
	- /sbin：システム管理に必須のコマンド、root ユーザのみ
		- shutdown、fdisk、...
	- /usr/bin：ユーザが一般的に使うコマンドで、緊急時のシステム保守に必須ではないもの
	- /usr/sbin：システム管理コマンドで、緊急時のシステム保守に必須ではないもの

- ファイルの検索
	- `$ find`
	- `$ locate`：あらかじめ作成されたデータベースに基づくため高速
		- `$ updatedb` で更新
	- `# which <command>`：絶対パスの表示
	- `# whereis <command>`：バイナリ、ソースコード、マニュアルファイルの絶対パス表示