Linux勉強会2016冬（第一回） 資料

#外部の方向けの注記
これはKMC（京大マイコンクラブ）で行った「Linux勉強会2016冬」（第一回）の資料です。

主に次世代のroot（部内サーバの管理者）を養成すること、および部員が部内サーバを有効に使えるようになることを志向しています。

今回は最も基本的なことです（私が高度なことはしらないので）。部内サーバー（ホスト名は`ringo`、ディストリビューションはdevian 8）に`ssh`したところから始まります。

#まずはlsから
`ls`はディレクトリ（＝フォルダ）の中身が何かを出力するコマンドです。

```bash:
suzusime@ringo:~$ ls
backups    chef-solo  ctf        dotfiles  extlib  infra       maru.zip      projects      test.txt
bushi.txt  codes      documents  download  images  install.sh  private_html  pukiwiki.tar  texmf
```

`-l`をつけると詳細がでるようになります。こういうものを（コマンドライン）オプションといいます。

```bash:
suzusime@ringo:~$ ls -l
合計 195928
drwxr-xr-x  2 suzusime kmc      4096  2月  7  2016 backups
-rw-r--r--  1 suzusime kmc     49272  5月 29  2016 bushi.txt
drwx------  8 suzusime kmc      4096  2月 14  2016 chef-solo
drwxr-xr-x 21 suzusime kmc      4096 11月  8 12:30 codes
drwxr-xr-x  2 suzusime kmc      4096 10月 27 16:44 ctf
drwxr-xr-x  2 suzusime kmc      4096  2月 10  2016 documents
drwxr-xr-x  3 suzusime kmc      4096 11月 25 22:27 dotfiles
drwxr-xr-x  3 suzusime kmc      4096 11月  3 11:21 download
drwxr-xr-x  3 suzusime kmc      4096 12月 13  2015 extlib
drwxr-xr-x  2 suzusime kmc     28672  3月 29  2016 images
drwxr-xr-x  3 suzusime kmc      4096  2月 13  2016 infra
-rw-r--r--  1 suzusime kmc      4149  1月 23  2016 install.sh
-rwxr-x---  1 suzusime kmc   2027510  2月  5  2016 maru.zip
drwxr-xr-x  5 suzusime kmc      4096 10月 15 15:39 private_html
drwxr-xr-x  3 suzusime kmc      4096  4月 21  2016 projects
-rw-r--r--  1 suzusime kmc 198451200  4月 25  2016 pukiwiki.tar
-rw-r--r--  1 suzusime kmc        78  6月 11 14:50 test.txt
drwxr-xr-x  6 suzusime kmc      4096  1月 15  2016 texmf
```

`-a`をつけると隠しファイルも含めた全てのファイルが表示されます。Linuxでは先頭に`.`がついたファイルは隠しファイルとして扱われます。

```bash:
suzusime@ringo:~$ ls -a
.              .emacs.d              .muttrc          .rbenv           .viminfo.tmp  bushi.txt  infra
..             .forever              .node-gyp        .scala_history   .vimrc        chef-solo  install.sh
.FontForge     .forward              .npm             .sqlite_history  .vimshell     codes      maru.zip
.aptitude      .gem                  .nvm             .ssh             .weechat      ctf        private_html
.bash_history  .gitconfig            .omake           .texmf-config    .zcompdump    documents  projects
.bash_logout   .gnutls               .pip             .texmf-var       .zsh_history  dotfiles   pukiwiki.tar
.bashrc        .kmc-profile          .profile         .tmux.conf       .zshenv       download   test.txt
.cache         .kmc-profile.example  .pyenv           .vim             .zshrc        extlib     texmf
.config        .maildir              .python_history  .viminfo         backups       images
```

恐らくみなさんのホームディレクトリにも`.bashrc`などの隠しファイルや`.ssh`などの隠しディレクトリ（フォルダ）が入っているはずです。このような設定ファイル類は隠しファイルになっていることがよくあります。

`$ ls -al`または`$ ls -l -a`のようにオプションをふたつとも指定してやると、全てのファイル/ディレクトリの詳細情報が出力されます。

次はディレクトリを指定してその中身を表示させてみましょう。

```bash:
suzusime@ringo:~$ ls /home/suzusime/.ssh
authorized_keys  config  id_rsa  id_rsa.pub  known_hosts
```

このように引数にディレクトリの名前を指定してやることでそのディレクトリの中身を表示してくれます。

Linuxのパス（＝場所を表す情報）はスラッシュで区切ります。`/`が一番上（ルート（根）とよびます）で、その下に`/home`、`/etc`、`/bin`などなどがあります。

先程のように`ls`のあと（引数）になにも指定しなかったときはカレントディレクトリ（＝今いるディレクトリ）の情報を表示します。カレントディレクトリの情報は`pwd`で表示できます。

```bash:
suzusime@ringo:~$ pwd
/home/suzusime
```

基本的に端末を起動した直後や`ssh`した直後などは`/home/user名`というディレクトリがカレントディレクトリになります。これをホームディレクトリといいます。だいたいの私的な作業はこのディレクトリの下でやりましょう。

なお、ホームディレクトリのパスは`~`で代用することができます（追記：これはLinuxそのものの機能ではなくbash（shell）による機能らしいです）。たとえば`~/.ssh`とかけば、それは`/home/user名/.ssh`を意味します。上の例ではずっとコマンドの左に`suzusime@ringo:~$`という文字がでていると思いますが、ここにある`~`はカレントディレクトリが`~`であることを意味しています。

上の`/home/suzusime/.ssh`は絶対パスと呼ばれる表示法です。他に相対パスという表示法があります。相対パスは今いるディレクトリからの相対的な位置で表示する方法で、例えばカレントディレクトリが`/home/suzusime/`ならば`.ssh`と書くだけで`/home/suzusime/.ssh`を指し示すことができます。ひとつ上（親）のディレクトリは`../`で示します。この場合、`../`は`/home`を、`../wass80`は`/home/wass80`を指すことになります。

カレントディレクトリの移動は`cd`コマンドです。

```bash:
suzusime@ringo:~$ cd .ssh
suzusime@ringo:~/.ssh$ pwd
/home/suzusime/.ssh
```

カレントディレクトリを作業するファイルがある場所に移動しておくとパスが簡単になって作業が楽になります。

#ファイル操作いろいろ
##mkdir
`mkdir`は空のディレクトリをカレントディレクトリに生成するコマンドです。

```bash:
suzusime@ringo:~$ mkdir test
suzusime@ringo:~$ cd test
suzusime@ringo:~/test$ pwd
/home/suzusime/test
```

##touch
`touch`は空のファイルをカレントディレクトリに生成するコマンドです（本来は別の用途なのですが………）。

```bash:
suzusime@ringo:~/test$ touch hoge
suzusime@ringo:~/test$ ls
hoge
```

##chmod
`chmod`はファイルのパーミッション（＝アクセス権限）を変更するコマンドです。

```bash:
suzusime@ringo:~/test$ ls -l
合計 0
-rw-r--r-- 1 suzusime kmc 0 12月  2 12:29 hoge
suzusime@ringo:~/test$ chmod 755 hoge
suzusime@ringo:~/test$ ls -l
合計 0
-rwxr-xr-x 1 suzusime kmc 0 12月  2 12:29 hoge
```

`ls -l`をしたときに一番左の列にでているのがパーミッションの情報です。

`r`が読み取り権限、`w`が書き込み権限、`x`が実行権限を示します。例えば`rw-`であれば読み込みと書き込みの権限があり実行の権限はないことになります。`rw-r--r--`のように3つ並んでいると思いますが、これは左からそれぞれファイルの所有者（この場合suzusime）、ファイルのグループ（この場合kmc）、それ以外のユーザーの権限を示しています。

`rw-`のような記法は少し面倒なので、これを数字で表す方法があります。`r`には4、`w`には2、`x`には1を割り当てて数字の和で権限を示します。例えば`rw-`なら4+2で6です。これを3つ並べて、`rw-r--r--`は`644`とあらわすことになります。上では`$ chmod 755 hoge`としていますが、これによってhogeのパーミッションが`755`に変わっているのが分かります。なお、`$chmod u+x hoge`のように数字を使わずに指定することもできます。

だいたいのファイルは`644`（ディレクトリの場合は`755`）にしておけばいいと思います（親ディレクトリのパーミッションを引き継ぐのでたいていこうなっています）。ただし、他のユーザーに見られたくないファイル（例えば秘密鍵ファイル`~/.ssh/id_rsa`は他のユーザーに見られるととてもまずい）は`600`のようにしておきましょう。
また、間違って`000`のファイルを作ってしまうと自分でも削除や編集ができなくなってrootに頼むしかなくなるので注意してください。
（訂正：所有者が自分ならば`chmod`で修正することができるらしいです）

- [ファイルのパーミッション設定、ディレクトリは要注意](http://wordpress.honobono-life.info/lin-base/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E8%A8%AD%E5%AE%9A%E3%80%81%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AF/)：ディレクトリのパーミッションの挙動はいささか直観に反するので読みましょう。

##echo、cat
`echo`は引数をそのまま返すコマンドです。

```bash:
suzusime@ringo:~/test$ echo にゃーん
にゃーん
```

このままだとあまり意味がなさそうに見えますが、リダイレクトという機能を用いるとファイルに書き込むことができます。

```bash:
suzusime@ringo:~/test$ echo にゃーん > hoge
suzusime@ringo:~/test$ cat hoge
にゃーん
```

ここででてきた`cat`コマンドはファイルの中身を出力するコマンドです（本当はファイルを結合するためのコマンドなのですが）。`hoge`のなかに`にゃーん`と書き込まれていることがわかります。`>`を使うと、標準出力（この場合端末（画面）に出力されてくる文字だと思ってください）を代わりにファイルのなかに出力することができます。これがリダイレクトです。

`>`は出力先のファイルの全文を置き換えてしまうのですが、かわりに`>>`を使うと追記させることができます。また、標準出力とは別の系統でエラー出力というものがあり、これの出力先を変えるときには`2>`や`2>>`を使います（エラー出力はその名の通りエラーが発生したときの警告文の出力などに主に使われます。何も指定しないときはふつう標準出力とエラー出力の内容はともに端末に表示されるようになっています）。

- `echo`と`cat`があればファイルの内容を編集することができます。`#shell`では標準的なエディタとしてよく使われていました…… なお`head`や`tail`などをうまく使うと編集効率があがりそうです。

##grep
次のようなコマンドを打ってみてください。大量のデータが表示されると思います。

```bash:
suzusime@ringo:~/test$ ps aux
```

これはこのコンピュータで動いているプロセス（プログラムの単位みたいなものです）の一覧を表示するプログラムです。動いているプロセスを殺す（止める）際にはここからpid（プロセスのID）を探してその番号を`kill`コマンドに渡すのが基本なのですが、たくさんあってここから探すのは困難です。

ここから`tmux`というプログラムを探したいという場合には次のようにします。

```bash:
suzusime@ringo:~/test$ ps aux | grep tmux
```

こうすることで`tmux`という文字列が含まれる行だけが表示されたはずです。`grep`は検索コマンドで、ファイルの中や標準入力から指定されたパターンを含む部分を抽出してくれます。

`$ grep [パターン] [ファイル名]`だとファイルのなかから、`$ grep [パターン]`だと標準入力から検索します。

標準入力はふつう端末で入力した文字列になります。例えば`$ grep yu`を実行してみてください。入力待機画面になると思います。この状態で`rika`や`hanyu`などと入力してエンターキーを押してみると、`hanyu`のときだけ`hanyu`という出力が返ってくると思います。これは、`grep`が標準入力から`hanyu`という文字列を受け取ってそれがパターン`yu`にマッチすることからそれを出力したということです。`rika`ならば何も返ってこないはずです。

なお、標準入力の待機画面からは`^D`(Ctrl+Dの意味)を入力すると抜けることができます。ちなみに`^C`を入力するとほとんどのプログラムを強制終了させることができるので覚えておきましょう。

さて、先ほどの`$ ps aux | grep tmux`では`|`が重要な役割を果たしています。`|`はパイプとよばれ、左側のプログラムの標準出力を右側のプログラムの標準入力に渡します。今回の場合、`ps`の結果が標準出力に出力され、これを標準入力から受け取った`grep`が該当する行だけを出力しているのです。`grep`の出力も標準出力ですから、もちろん

```bash:
suzusime@ringo:~/test$ ps aux | grep tmux > hoge
```

とすれば`hoge`にその内容を書き込むことができます。

（追記：また、`<`を使うことでファイルの内容を標準入力に与えることができます。忘れていました）

こういう風に、Linuxでは単純な機能のプログラムをパイプやリダイレクトなどをうまく使っていくつか組み合わせて望む機能を実現させることが多いです。このような設計思想は「Unix哲学」と呼ばれています。

#テキストエディタ
Linuxでは設定ファイルはふつうすべてテキストデータで書かれることになっています。そのため、何をするにしてもテキストファイルの編集が必要になります。従って、Linuxをまともに使うためにはテキストエディタを使える必要があります。

上で述べたように`cat`と`echo`で編集するなんてことも不可能ではないですが、普通はもっとまともなプログラムを使います。代表的なのは`vim`と`emacs`ですが、宗教戦争で有名です。私は`vim`を使っていますが、ここでは`nano`、`vim`、`emacs`を紹介しておきます。

##nano
```bash:
suzusime@ringo:~/test$ nano hoge
```

で起動します。操作方法は下にでてくるのでそれを読めばわかります。とても単純です。

##vim
```bash:
suzusime@ringo:~/test$ vim hoge
```

vimは「モード」の概念がありややこしいです。起動したときは「通常モード」であり、この状態ではカーソルの移動などはできますが文字入力はできません。文字入力のできる「挿入モード」に入るには`i`を押します。通常モードに戻るには`Esc`です。上書き保存は通常モードで`:w`と入力してエンターを押します。終了は通常モードで`:q`です。変更を保存しないで終了すると怒られますが、`:q!`と入力すると無理やり終了させられます。

他にもたくさんの機能がありますが、最低限これを覚えておけば基本的なテキスト編集はできると思います。

##emacs
```bash:
suzusime@ringo:~/test$ emacs hoge
```

emacsにはモードの概念はないので入力すればそれがそのまま反映されます。上書き保存は`C-x C-s`（Ctrl+Xのあと続けてCtrl+Sの意）、終了は`C-x C-c`です。

こちらも他にもたくさんの機能があります。

#ネットワーク関連
## ip
```bash:
suzusime@ringo:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
    inet ***.***.***.***/** brd ***.***.***.*** scope global eth0
       valid_lft forever preferred_lft forever
    inet6 ****:****:****:****:****:****/** scope link
       valid_lft forever preferred_lft forever
```

`$ ip addr`を引数無しで実行すると現在のIPアドレスなどのネットワークの状態を表示することができます（まずそうなところは伏字にしました）。

2の`eth0`というのがこのコンピュータに外部からつながっているネットワークカードのアドレス情報です。`inet`のあとの`192.168.0.1`のような数字がIPアドレス（IPv4アドレス）です。外部からこのコンピュータに接続する場合にはこのアドレス及びポート（後述）を指定すればよいことになります。

ポートというのは各プログラムが通信する際の窓口のようなもので、1つのIPアドレスにたいして0～65535番のポートがあります。例えば、`192.168.0.1:22`はIPアドレスが`192.168.0.1`のコンピュータ（ネットワークカード）の`22`番ポートを指します。

##nc
`nc`（netcat）はネットワーク関連のいろいろなことができるコマンドです。

```bash:
suzusime@ringo:~$ nc -l -p 9494
```

上を実行することでこのコンピュータの`9494`番ポートに通信を待ち受けるサーバーを立てることができます。別の端末を開き、

```bash:
suzusime@ringo:~$ nc 127.0.0.1 9494
```

とすると標準入力の待機画面になるので、そこでなにか入力してエンターキーを押してやると、先ほどサーバーを立てた方の端末にその内容が出力されるはずです。これでサーバーとクライアントのあいだの通信ができているわけです。これだけで簡単なチャットができてしまいます。

`127.0.0.1`は自分自身を表すIPアドレスです（上の`$ip addr`の結果の`lo`のところにでています）。`localhost`という文字列に変えても同じです。ここに代わりに`192.168.0.1`のようなIPアドレスを入れると、ネットワークにつながっている別のコンピュータに対しても同じように通信ができることになります。ぜひ部員の間で試してみてください。

他にも

```bash:
suzusime@ringo:~$ nc kmc.gr.jp 80
```

として`GET /`や空白を送ってやるとWebサーバーがどういう応答を返しているのかが分かって面白いと思います。