新しいLinuxの教科書　読了メモ

# Introduction
新しいLinuxの教科書でLinuxを一から勉強していく．
コマンドなどはDocker環境でおこなう．

https://www.amazon.co.jp/%E6%96%B0%E3%81%97%E3%81%84Linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E4%B8%89%E5%AE%85-%E8%8B%B1%E6%98%8E-ebook/dp/B072K1NH76/ref=sr_1_1?adgrpid=113196705062&hvadid=651122190449&hvdev=c&hvlocphy=1028853&hvnetw=g&hvqmt=e&hvrand=10863380054048201265&hvtargid=kwd-1152146940662&hydadcr=21814_13455335&jp-ad-ap=0&keywords=%E6%96%B0%E3%81%97%E3%81%84linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8&qid=1690100203&sr=8-1

```dockerfile:Dockerfile
FROM ubuntu:18.04

ARG USERNAME=user
ARG GROUPNAME=user
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID $GROUPNAME && \
    useradd -m -s /bin/bash -u $UID -g $GID $USERNAME
USER $USERNAME
```

```yml: docker-compose.yml
services:
  server:
    image: ubuntu:18
    build: .
    container_name: ubuntu18
    working_dir: /home/user/workspace
    volumes:
      - ./workspace:/home/user/workspace
    tty: true
```

使用するdockerコマンド
```
# コンテナ作成，起動
docker compose up -d

# コンテナの停止
docker compose down

# コンテナのシェルに一般ユーザーで接続
docker compose exec server /bin/bash

# コンテナのシェルにrootユーザーで接続
docker compose exec -u root server /bin/bash

# コンテナのシェルから抜ける
exit
```

# Chapter02 シェルって何だろう
## プロンプト
ユーザー名@ホスト名:カレントディレクトリ
```
user@083a3f79e474:~/workspace$
```
一般ユーザ
```
$ <コマンド>
```
スーパーユーザー
```
# <コマンド>
```
ログインシェルの確認
```
$ echo $SHELL
/bin/bash
```

## シェルの種類
- sh：シェルスクリプト利用におススメ！
  - もっとも古くから存在するシェル．
  - シェルスクリプトを書く際にはshを利用するのが一般的
  - 機能は少なく対話的に使うには不便
- csh：Cシェルと呼ばれshに比べ対話的操作が便利になる
- bash：一番おススメ！
  - 対話的操作を行う上で十分な機能を持つ
  - 多くのLinux環境でデフォルトのログインシェルとして使われる
  - シェルスクリプトを書くのにも向いている
- tcsh：cshの後継として開発され，対話型操作で便利な機能を持つ
- zsh：非常に多くの機能をもつが初心者向けのシェルではない

## コマンドでシェルを切り替える
bashからsh，shからbashへ切り替える
```
user@083a3f79e474:~/workspace$ sh
$ bash
user@083a3f79e474:~/workspace$
```

# Chapter03 シェルの便利な機能
カーソル位置から行頭まで削除`Ctrl + u`
画面ロック：`Ctrl + s`
画面ロック解除`Ctrl + q`
画面をクリア：`Ctrl + l`
過去のコマンドを検索：`Ctrl + r`


補完：`Tab`を2回押す
```
$ e    <-Tabを2回押す
e2freefrag  e2image     e2undo      e4defrag    egrep       else        env         eval        exit        expiry      expr        
e2fsck      e2label     e4crypt     echo        elif        enable      esac        exec        expand      export
```

# Chapter04 ファイルとディレクトリ
## 各ディレクトリの役割
- /bin：一般ユーザおよび管理者ユーザの両方が利用する，Linuxシステムの動作に最低限必要な重要度の高いコマンドを格納．
- /dev：デバイスファイルを格納する．ディスクやキーボードなどのハードウェアをファイルとして扱えるように用意されたディレクトリ．
- /etc：設定ファイルを置く．
- /home：ユーザごとに割り当てられるホームディレクトリが配置される．
- /sbin：管理者ユーザー向けのコマンドが置かれている．
- /tmp：一時的なファイルを置く．
- /usr：各種アプリケーションと，それに付随するファイルを置く
- /var：アプリケーションを動作する上で作成されたデータやログ，電子メールなどの変化するデータを置く．

## 各コマンド
- `pwd`：カレントディレクトリの表示
- `cd`：ディレクトリの移動
- `ls`:ファイルやディレクトリの一覧表示

## cdコマンド
- `cd /`：ルートディレクトリに移動
- `cd ~`：ホームディレクトリに移動
- `cd Tab`：パスの補間
```
# ルートディレクトリに移動
$ cd /
$ pwd
/

# ホームディレクトリに移動
$ cd ~
$ pwd
/home/user

# パスの補間
$ cd　Tab押す
.dockerenv  dev/        lib/        mnt/        root/       srv/        usr/
bin/        etc/        lib64/      opt/        run/        sys/        var/
boot/       home/       media/      proc/       sbin/       tmp/
```

## lsコマンド
- `ls *`
- `ls ?`
```
# tで終わるディレクトリを表示
$  ls *t
boot:

mnt:

opt:

root:

# tで終わる3文字のディレクトリを表示
$ ls ??t
mnt:

opt:
```

- `ls -a`：ファイル名が`.`で始まる隠しファイルも表示
- `ls -l`：ファイルの詳細表示
- `ls -F`：ファイルの種類を表示
```
# 隠しファイル表示
$ ls -a
.   .dockerenv  boot  etc   lib    media  opt   root  sbin  sys  usr
..  bin         dev   home  lib64  mnt    proc  run   srv   tmp  var

# ファイルの詳細表示
$ ls -l
total 68
drwxr-xr-x   2 root root 4096 May 30 02:04 bin
drwxr-xr-x   2 root root 4096 Apr 24  2018 boot
drwxr-xr-x   5 root root  360 Jul 23 07:41 dev
drwxr-xr-x   1 root root 4096 Jul 23 08:41 etc
drwxr-xr-x   1 root root 4096 Jul 23 07:41 home
drwxr-xr-x   8 root root 4096 May 23  2017 lib
drwxr-xr-x   2 root root 4096 May 30 02:03 lib64
drwxr-xr-x   2 root root 4096 May 30 02:03 media
drwxr-xr-x   2 root root 4096 May 30 02:03 mnt
drwxr-xr-x   2 root root 4096 May 30 02:03 opt
dr-xr-xr-x 266 root root    0 Jul 23 07:41 proc
drwx------   1 root root 4096 Jul 23 08:41 root
drwxr-xr-x   5 root root 4096 May 30 02:04 run
drwxr-xr-x   2 root root 4096 May 30 02:04 sbin
drwxr-xr-x   2 root root 4096 May 30 02:03 srv
dr-xr-xr-x  11 root root    0 Jul 23 07:41 sys
drwxrwxrwt   1 root root 4096 Jul 23 08:41 tmp
drwxr-xr-x  10 root root 4096 May 30 02:03 usr
drwxr-xr-x   1 root root 4096 Jul 23 08:41 var

# ファイルの種類表示
$ ls -F
bin/   dev/  home/  lib64/  mnt/  proc/  run/   srv/  tmp/  var/
boot/  etc/  lib/   media/  opt/  root/  sbin/  sys/  usr/

# 2つのオプションを指定
$ ls -aF
./   .dockerenv*  boot/  etc/   lib/    media/  opt/   root/  sbin/  sys/  usr/
../  bin/         dev/   home/  lib64/  mnt/    proc/  run/   srv/   tmp/  var/
```

# Chapter05 ファイル操作の基本
## mkdirコマンド
- `mkdir`：ディレクトリを作成する
- `mkdir -p`：ディレクトリを一気に作成する
```
# ディレクトリを作成
$ mkdir report
$ ls
report

# ディレクトリを一気に作成
$ mkdir -p report/2023/07
$  ls report
2023
```

## touchコマンド
- `touch`：ファイルを作成する
```
$ touch newfile
$ ls -F
newfile  report/
```

## rmとrmdirコマンド
- `rm`：ファイルを削除する
- `rmdir`：空ディレクトリを削除する
- `rm -r`：空でないディレクトリも完全に削除する
```
# ファイルを削除する
$  rm newfile
$ ls
report

$ rmdir report
rmdir: failed to remove 'report': Directory not empty

$ rm -r report
$ls

```
## catコマンド
- `cat`：ファイルの中身を表示する
```
$ cat /etc/hostname
32d855919060
```

## cpコマンド
- `cp`：ファイルのコピー
- `cp -r` :ディレクトリのコピー
```
# ファイルのコピー
$ touch file1
$ cp file1 file2
$ ls
file1  file2

# ファイルを別のディレクトリ内にコピー
$ mkdir dir1
$ cp file1 dir1
$ ls dir1
file1

# ディレクトリをコピー
$ cp -r dir1 dir2
$ ls dir2
file1
```

## lnコマンド
- `ln -s`：シンボリックリンクを張る
- `ls -l`：リンクを確認する

シンボリックリンクの活用方法
- シンボリックリンクを活用すると長いパス名を省略できる
- 複数バージョンのプログラムを共存させ切り替える
```
$ mkdir -p local/work/code/project/source
$ ln -s local/work/code/project/source
$ ls -l
total 0
drwxr-xr-x 2 root root 60 Jul 30 14:24 dir1
drwxr-xr-x 2 root root 60 Jul 30 14:25 dir2
-rw-r--r-- 1 root root  0 Jul 30 14:23 file1
-rw-r--r-- 1 root root  0 Jul 30 14:23 file2
drwxr-xr-x 3 root root 60 Jul 30 14:38 local
lrwxrwxrwx 1 root root 30 Jul 30 14:38 source -> local/work/code/project/source

$ cd source
$ pwd
/home/user/workspace/source
```

# Chapter06 探す，調べる
- `find 検索開始ディレクトリ -name`：ファイル名を指定して検索
- `find 検索開始ディレクトリ -type タイプ`：タイプを指定して検索
```
$ touch file1.txt ch06/file1.txt ch06/file2.txt

# ファイル名を指定して検索
$ find . -name file1.txt
./file1.txt
./ch06/file1.txt

# ワイルドカードを指定して検索
$ find -name '*.txt'
./file1.txt
./ch06/file2.txt
./ch06/file1.txt

# タイプがファイルのみ検索
$ find . -type f
./file1.txt
./ch06/file1.txt
./dir2/file1
./dir1/file1
./file2
./file1

# タイプがディレクトリのみ検索
$ find . -type d
.
./ch06
./ch06/file2.txt
./local
./local/work
./local/work/code
./local/work/code/project
./local/work/code/project/source
./dir2
./dir1
```

## コマンドの使い方を調べる
`--help`：コマンドのヘルプを表示
```
$ cat --help
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s) to standard output.

With no FILE, or when FILE is -, read standard input.

  -A, --show-all           equivalent to -vET
  -b, --number-nonblank    number nonempty output lines, overrides -n
  -e                       equivalent to -vE
  -E, --show-ends          display $ at end of each line
  -n, --number             number all output lines
  -s, --squeeze-blank      suppress repeated empty output lines
  -t                       equivalent to -vT
  -T, --show-tabs          display TAB characters as ^I
  -u                       (ignored)
  -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB
      --help     display this help and exit
      --version  output version information and exit

Examples:
  cat f - g  Output f's contents, then standard input, then g's contents.
  cat        Copy standard input to standard output.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report cat translation bugs to <http://translationproject.org/team/>
Full documentation at: <http://www.gnu.org/software/coreutils/cat>
or available locally via: info '(coreutils) cat invocation'
```

## コマンドを探す
`which` :フルパスを検索する
```
$  which cat
/bin/cat
```

# Chapter07 テキストエディタ
ルートユーザでログイン
```
docker compose exec -u root server /bin/bash
```
vimのインストール
```
$ apt-get update
$ apt-get install vim
```

## ファイルを開く/保存する
- `vim`：vimを起動する
- `:w`：ファイルを上書き保存する
- `:q`：vimを終了する
- `:q!`：ファイルを保存せず終了する
```
# ファイル名を指定してvimを起動
$ vim ch07.txt

# ファイルの保存
:w

# vimの終了
:q

$ ls
ch07.txt
```

## Vimの編集操作
`i`：インサートモードに切り替える
`Esc`：ノーマルモードに切り替える
```
$ vim ch07.txt

# インサートモードに切り替え
i
# 文字入力
ch07 insert
# ノーマルモードに切り替え
Esc
# ファイルの保存
:w
# vimの終了
:q

$ cat ch07.txt
ch07 insert
```

# Chapter08 bashの設定
## シェル変数
```
$ var1='test variable'
$ echo $var1
test variable
```

- `$PS1`：プロンプトの設定を格納した変数
```
$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$

# プロンプトの表示を変更する
$ PS1='\W\$'  
workspace#
```

シェルの状態関連のシェル変数
- `HOME`：ホームディレクトリ
- `SHELL`：ログインシェルのパス
- `PWD`：カレントディレクトリ
```
$ echo $HOME
/home/user

$ echo $SHELL
/bin/bash

$ echo $PWD
/home/user/workspace
```

## 環境変数
- `printenv`：環境変数の表示
```
$ printenv
HOSTNAME=083a3f79e474
PWD=/home/user/workspace
HOME=/home/user
TERM=xterm
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
_=/usr/bin/printenv
```

# Ch09 ファイルパーミッション，スーパーユーザー
## ファイル権限の確認
- `-`：ファイルタイプ
  - `-`：通常ファイル
  - `d`：ディレクトリ
  - `l`：シンボリックリンク
- `rwxr-xr-x`：ファイルのパーミッション（オーナー　グループ　その他ユーザー）
  - `r`：読み取り
  - `w`：書き込み
  - `x`：実行
- `root root`：ファイルの所有者　ファイルが所属するグループ
```
$ ls -l /bin/cat
-rwxr-xr-x 1 root root 35064 Jan 18  2018 /bin/cat
```

## chmodコマンド
- `chmod <8進数の数値> <ファイル名>`：ファイルの権限を変更する
  - 4：読み取り
  - 2：書き込み
  - 1：実行

```
$ touch ch09
$ ls -l ch09
-rw-r--r-- 1 user user 0 Aug  2 12:13 ch08

$ chmod 755 ch09
$ ls -l ch09
-rwxr-xr-x 1 user user 0 Aug  2 12:13 ch08
```

## スーパーユーザ
スーパーユーザ（rootユーザ）とは管理者権限を持つ特別なユーザ
- `su`：スーパーユーザーになる
- `exit`：一般ユーザに戻る
- `sudo <コマンド>`：スーパーユーザとしてコマンドを実行する


# Chapter10 プロセスとジョブ
## プロセスとは
メモリ上で実行状態にあるプログラムのことをプロセスと呼ぶ
- `ps`：プロセスの表示
PIDはプロセスID，TTYはターミナル，CMDはコマンドを表す
```
$ ps
  PID TTY          TIME CMD
  571 pts/1    00:00:00 bash
  581 pts/1    00:00:00 ps
```
psコマンドのオプション
- `x`：ps コマンドを実行したユーザのプロセスすべてを表示
- `ux`：ps コマンドを実行したユーザのプロセスすべてを詳細表示
- `ax`：すべてのユーザのプロセスを表示
- `aux`：すべてのユーザのプロセスを詳細表示
以下の例では，ホストPCからの接続がpts/1を，DockerDesktopからの接続がpts/2となっている．
```
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user         1  0.0  0.3  18516  2860 pts/0    Ss+  Aug02   0:00 /bin/bash
user       571  0.0  0.3  18508  3472 pts/1    Ss   12:30   0:00 /bin/bash
user       586  0.0  0.0   4636   880 pts/2    Ss   12:40   0:00 /bin/sh
user       594  0.0  0.0   4636   776 pts/2    S+   12:40   0:00 sh
user       602  0.0  0.3  34412  2904 pts/1    R+   12:47   0:00 ps aux
```

## ジョブとは
プロセスはLinuxカーネルから見た処理の単位であり，シェルから見た処理の単位をジョブという．
- `Ctrl + Z`：ジョブを停止する
- `jobs`：ジョブを表示する
- `fg %<ジョブ番号>`：ジョブをフォアグラウンドにする（停止中のジョブを再開する）
- `bg %<ジョブ番号>`：ジョブをバックグラウンドにする(処理を実行したままシェルに戻る)

以下の作業はDocker Desktopのterminalで行う．Ctrl + Zでdockerから抜けてしまうため
```:ジョブの停止
$ vim ch10.txt
Ctrl + Zを押す
[1] + Stopped                    vim ch10.txt
$ jobs
[1] + Stopped                    vim ch10.txt
```

vimでの編集作業を一時停止して，他のコマンドを実行したいときに使用すると便利
```:ジョブをフォアグラウンドに
$ fg %1
停止中のVIMが起動する
vim ch10.txt
```

## ジョブ・プロセスの終了
`Ctrl + C`：実行中のジョブを終了
`kill %<ジョブ番号>`：バックグラウンドジョブを終了する
`kill <プロセスID>`：プロセスを終了する


# Chapter11 標準入力とパイプライン
標準入力（stdin）：プログラムの標準的な入力．通常はキーボードが使われる．
標準出力（stdout）：プログラムの標準的な出力．通常は端末ディスプレイが使われる．
標準エラー出力（stderr）：エラーメッセージを出力．

## リダイレクト
入力リダイレクト：キーボードの代わりにファイルなどを標準入力につなぐこと．ファイルを指定するよりも汎用性が高く，ほかのプログラムとの連携もしやすい．
```
$ cat < /etc/hostname
083a3f79e474
```

標準出力のリダイレクト
```
$ ls / > list.txt
user@083a3f79e474:~/workspace$ cat list.txt
bin
boot
dev
etc
...
```

標準出力と標準エラー出力の両方を1つのファイルにまとめる
標準エラー出力(2)を標準出力(1)と同じファイルへ2>&1と書いてリダイレクトしている
標準入力を表す数値は1
```
$ ls /xxx > result.txt 2>&1
$ cat result.txt
ls: cannot access '/xxx': No such file or directory
```

`>`は上書き，`>>`は追記となる
```
$ ls /xxx >> result.txt 2>&1
$ cat result.txt
ls: cannot access '/xxx': No such file or directory
ls: cannot access '/xxx': No such file or directory
```

## パイプライン
パイプライン：コマンドの標準出力を別のコマンドの標準入力につなぐこと
```
ls / | cat -n
     1  bin
     2  boot
     3  dev
     4  etc
     5  home
...
```

## フィルタ
先頭の部分を表示したり，順番に並べたりすることができるコマンド
```
$ ls / | cat -n | head
     1  bin
     2  boot
     3  dev
     4  etc
     5  home
     6  lib
     7  lib64
     8  media
     9  mnt
    10  opt
```

ファイルサイズの大きい上位5つを表示
```
$ du -b /bin/* | sort -n | tac | head -n 5
1113504 /bin/bash
423312  /bin/tar
219456  /bin/grep
141528  /bin/cp
137440  /bin/mv
```


# Chapter12 テキスト処理
テキスト処理に便利なコマンド
- `wc`：行数，単語数，バイト数を数える
- `sort`：行単位でテキストをソートする
- `uniq`：重複を取り除く
- `cut`：入力の一部を切り出す
- `tr`：文字を変換・削除する
- `tail`：末尾を表示
- `diff`：差分を表示する
```
wc /etc/passwd
 20  25 965 /etc/passwd
```


# Chapter13 正規表現
## grepコマンドと正規表現
- `grep　<検索パターン> <ファイル名>`：文字列を検索する
  - オプション`-i`：大文字と小文字を区別しない
  - オプション`-v`：含まない行を出力
```
$grep bash /etc/passwd
root:x:0:0:root:/root:/bin/bash
user:x:1000:1000::/home/user:/bin/bash
```
```
$ ls /etc | grep cron
cron.daily
```

正規表現：条件に合致する文字列集合を表現するための記法
## 文字にマッチするメタ文字
`.`：任意の位置文字を表す
`[文字]`：特定の文字を指定する
`[0-9]`：数字にマッチする
`[^文字]`：指定した文字以外
```
$ ls /etc | grep 'l.e'
alternatives
```

## 位置にマッチするメタ文字

- `^文字`：先頭が指定した文字で始まる
- `文字$`：行末が指定した文字で終わる
```
$ ls /etc | grep '^a'
adduser.conf
alternatives
apt
```
```
$ ls /etc | grep 's$'
alternatives
hosts
login.defs
mime.types
networks
shells
```

## 繰り返しを指定するメタ文字
`*文字`：指定した文字が0回以上繰り返す

```
$ ls /etc | grep -E '*ls'
lsb-release
shells
```
拡張正規表現：`-E`オプションを利用すると拡張正規表現として解釈される
- `+`：1回以上繰り返す
- `?`：0回または1回の繰り返し
- `{m,n}`：m回以上n回以下の繰り返し
- `{m}`：ちょうどm回の繰り返し
- `{m,}`：m回以上の繰り返し
```
$ ls /etc | grep -E 'l{2}'
shells
```

## その他のメタ文字
`()`：グループ化
`|`：OR条件
```
$ cat ch13.txt
winwin
win
lose

$ grep -E '(win){2}' ch13.txt
winwin

$ grep -E '(win|lose)' ch13.txt
winwin
win
lose
```


# Chapter14 高度なテキスト処理
## sedコマンド
sedコマンドは非対話型エディタで，ファイルを編集し標準出力に出力することができる．元のファイルは変更されない．
`d`：行を削除する
`p`：行を表示する
`s/置換前/置換後`：行を置換する
```
$ cat ch14.txt
1
2
3
4
5

$ sed 1d ch14.txt
2
3
4
5

$ sed 2,4d ch14.txt
1
5

$ sed -n 3p ch14.txt
3

$ sed 's/1/a/' ch14.txt
a
2
3
4
5
```

## awkコマンド
awkコマンドはテキストの検索や抽出・加工などの編集操作を行う．
- `awk '{print $数字}'`：数字で指定した列を表示
- `awk '{print $NF}'`：NFは最後の列を表す
```:lsコマンドの結果から1,5,9列を表示
$ ls -l /usr/bin/ | awk '{print $1,$5,$9}'
total
-rwxr-xr-x 51384 [
-rwxr-xr-x 22608 addpart
-rwxr-xr-x 14424 apt
...

$ ls -l /usr/bin/ | awk '{print $NF}'
16120
[
addpart
apt
...
```


# Chapter15 シェルスクリプトを書こう
## シェルスクリプトの作成と実行
vimで以下のようなシェルスクリプトを記述する．
- `#!`はshebang(シバン)と呼ばれ，実行するシェルを指定する．
- `.sh`は無くても良いが，シェルスクリプトであることを明示したほうがよい．
```
$ vim homesize.sh
$ cat homesize.sh
#!/bin/bash
du -h ~ | tail -n 1
```

シェルスクリプトには実行権限を付与する必要がある．
```
$ chmod +x homesize.sh
```

シェルスクリプトは絶対パスもしくは相対パスで指定することで実行できる．
```
$ ./homesize.sh
56K     /home/user
```

## シェルスクリプトを配置する
pathを指定せずにシェルスクリプトを実行できるようにする．
まずは`~/bin`ディレクトリを作成しシェルスクリプトを移動
```
$ mkdir ~/bin
$ mv homesize.sh ~/bin
```

サーチパスに`~/bin`を追加
```
$PATH
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:

$ PATH=":$PATH:~/bin"
$PATH
bash: :/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:~/bin:
```

パスを指定しなくてもシェルスクリプトが実行できるようになる
```
$ homesize.sh
64K     /home/user
```


# Chapter16 シェルスクリプトの基礎知識
## シェルスクリプトの基本
- `\`：複数行で書く場合に使用
- `#`：コメントを記述

```:ch16_01.sh
#!/bin/bash

echo  \
"hello"
# echo "hello"
```
```
$ ./ch16_01.sh
hello
```

## 変数
変数に値を代入し，`$`で変数の値を参照できる
変数の注意点
- 代入時には`$`を付けない
- `=`の前後にはスペースを入れない
- 変数名にはアルファベットと数字とアンダースコアだけ
- 
```:ch16_02.sh
#!/bin/bash

homedir=/home
ls $homedir
ls $homedir/user
ls ${homedir}/user
```

```
$ ./ch16_02.sh
user
bin  workspace
bin  workspace
```

##  クォーティング
変数を有効にするには`""`で囲む必要がある
```:ch16_03.sh
#!/bin/bash
counrty=Japan
echo 'I came from $country'
echo "I came from $country"
```
```
$ ./ch16_03.sh
I came from $country
I came from Japan
```

## コマンド置換
`$()`：コマンドの結果を文字列として取得する際に使用
```:ch16_04.sh
#!/bin/bash

echo "Today is $(date)"
```

```
$ ./ch16_04.sh
Today is Fri Aug 11 06:26:23 UTC 2023
```

## 位置パラメータ
コマンドライン引数を使用するには位置パラメータと呼ばれるシェル変数を利用する．
- `$0`にはシェルスクリプト名を，`$1`以降はコマンドライン引数を格納
- `$#`はコマンドライン引数の数を格納
- コマンドライン引数に`*`を指定するとカレントディレクトリ内のファイル名が渡される
```:ch16_05.sh
#!/bin/bash

echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$# = $#"
```
```
$ ./ch16_05.sh a b
$0 = ./ch16_05.sh
$1 = a
$2 = b
$3 =
$# = 2
```
```
$ ./ch16_05.sh *
$0 = ./ch16_05.sh
$1 = ch08
$2 = ch10
$3 = ch10_copy
$# = 14
```

## 制御構造
if文
```:ch16_06if.sh
#!/bin/bash

if [ "$1" = "bin" ]; then
    echo "OK"
else
    echo "NG"
fi
```
```
$ ./ch16_06if bin
OK
$ ./ch16_06if bibi
NG
```

for文
```:ch16_06for.sh
#!/bin/bash

for param in $@
do
    echo $param
done
```
```
$ ./ch16_06for aa bb cc dd
aa
bb
cc
dd
```

## シェル関数
```:ch16_07.sh
#!/bin/bash

print_param ()
{
    echo "\$1 = $1"
    echo
    echo "$# arguments"
    echo "script name = $0"
}
print_param a b c
```
```
$ ./ch16_07.sh
$1 = a

3 arguments
script name = ./ch16_07.sh
```


# Chapter18 アーカイブと圧縮
アーカイブ：複数のファイルやディレクトリをまとめたファイル
## tarコマンド
`tar cf <アーカイブファイル> <アーカイブ元ファイル>`：アーカイブファイルを作成する
`tar tf <アーカイブファイル>`：アーカイブファイルの内容確認
`tar xf <アーカイブファイル>`：
```
$ mkdir ch18
$ touch ch18/file-(1..5).txt
$ ls ch18
file-1.txt  file-2.txt  file-3.txt  file-4.txt  file-5.txt
```
```
$ tar cf ch18.tar ch18

$ tar tf ch18.tar
ch18/
ch18/file-1.txt
ch18/file-2.txt
ch18/file-3.txt
ch18/file-4.txt
ch18/file-5.txt

$ rm -rf ch18
$ tar xf ch18.tar
$ ls ch18
file-1.txt  file-2.txt  file-3.txt  file-4.txt  file-5.txt
```

## gzipコマンド
`gzip <圧縮元ファイル>`：ファイルを圧縮する
```
$ ps aux > ps.txt
$ ls -l
total 0
-rw-r--r-- 1 user user 295 Aug 12 05:04 ps.txt

$ gzip ps.txt
$ ls -l
total 0
-rw-r--r-- 1 user user 192 Aug 12 05:04 ps.txt.gz
```

`tar czf`：アーカイブと圧縮を同時に行う
`tar czf`：アーカイブと圧縮を同時に行う
```
$ tar czf ch18.tar.gz ch18

$ ls -l
drwxr-xr-x 1 user user  4096 Aug 12 04:49 ch18
-rw-r--r-- 1 user user 10240 Aug 12 04:50 ch18.tar
-rw-r--r-- 1 user user   177 Aug 12 05:15 ch18.tar.gz

$ tar xzf ch18.tar.gz
```

## bzip2コマンド
bzip2はgzip形式よりも圧縮率が高く，データをより小さくできる．
`bzip2`：圧縮する
`bzip2 -d`展開する
`tar cjf`：アーカイブとbzip2形式の圧縮を同時に行う
```
$ tar cjf ch18.tar.bz2 ch18
```

## zipコマンド
zipはアーカイブと圧縮を同時に行える
`sudo apt-get install zip unzip`：パッケージのインストール
`zip -r <圧縮ファイル> <圧縮対象パス>`：zip形式で圧縮する
`zipinfo`：zipファイルの内容を確認
`unzip`：zipファイルの展開
`zip -er`：パスワード付きzipファイルの作成


# Chapter19 バージョン管理システム
## Gitのインストールと初期設定
rootユーザーでgitをインストール
```
# apt-get install git-core
```
初期設定
```
$ git config --global user.name 'user'
$ git config --global user.email 'user@example.com'                        
$ cat ~/.gitconfig
```

## 基本的な使い方
`git init`：リポジトリを作成
```
$ mkdir ch19
$ cd ch19 
$ git init
Initialized empty Git repository in /home/user/workspace/ch19/.git/
$ ls -a
.  ..  .git
```

`git  add <ファイル名>`インデックスにファイルを追加する
`git status`：ワークツリーの状態を表示する
`git commit -m <コミット名>`：リポジトリにファイルを登録する
```
$ vim test.sh
$ ls
test.sh
$ git add test.sh
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   test.sh

$ git commit -m 'add test'
```

 `git diff`：差分の表示
```
$ vim test.sh
$ git diff
diff --git a/test.sh b/test.sh
index 9daeafb..dec2cbe 100644
--- a/test.sh
+++ b/test.sh
@@ -1 +1,2 @@
 test
+test
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   test.sh

no changes added to commit (use "git add" and/or "git commit -a")
$ git add .
$ git commit 'change test.sh'
[master 1a6b42c] change test.sh
 1 file changed, 1 insertion(+)
```

`git log`：ログを確認する
```
$ git log
commit 1a6b42c9efbb9bc5eec6fbfd9e8ab7553e1d6f7f (HEAD -> master)
Author: user <user@example.com>
Date:   Sat Aug 19 04:26:43 2023 +0000

    change test.sh

commit aaad0d2c312b8143755374ff93ae4129d2246657
Author: user <user@example.com>
Date:   Sat Aug 19 04:23:48 2023 +0000

    add test
```

## ワークツリーとインデックス
`git diff --cached`：インデックスとリポジトリの差分を表示する
`git diff HEAD`：ワークツリーとリポジトリの差分を表示する

## コミットの単位
`git add -u`：変更したファイルをすべてインデックスに登録する
`git add -A`：すべてのファイルをインデックスに登録する

## 誤りから復旧する
`git checkout HEAD`：ワークツリーを元に戻す
`git revert ＜オブジェクト名＞`：コミットを取り消す
```
$ git rm test.sh
rm 'test.sh'
$ ls
$ git checkout HEAD .
$ ls
test.sh
```

## ブランチを使う
`git branch`：ブランチ一覧を表示する
`git branch <ブランチ名>`：新しいブランチを作成する
`git checkout <ブランチ名>`：ブランチを切り替える
`git merge <ブランチ名>`：ブランチをマージする
`git branch -d <ブランチ名>`：ブランチを削除する
```
$ git branch
* master
$ git branch feature
$ git branch
  feature
* master
$ git checkout feature
Switched to branch 'feature'
$ git branch
* feature
  master
$ git checkout master
Switched to branch 'master'
$ git branch -d feature
Deleted branch feature (was 1a6b42c).
$ git branch
* master
```

## リポジトリのバックアップを作成する
`git --bare init`：空のリポジトリを作成する
`git push <送信先リポジトリ> <送信元ブランチ>:<送信先ブランチ>`：変更の履歴を送る
`git clone <複製元リポジトリ>`：リポジトリを複製する


# Chapter20 ソフトウェアパッケージ
## yumコマンド
CentOSなどのRed Hat系のLinuxディストリビューションで使われる
`yum install <パッケージ名>`：パッケージのインストール

## aptによるパッケージ管理
UbuntuなどのDebian系のLinuxディストリビューションで使われる
`sudo apt-get install <パッケージ名>`：パッケージのインストール