Linux初心者あるある

理論系の研究室に配属された、計算機に明るくない人に説明する際の補助資料。
**内容には不正確なものを含む**

# Linux
WindowsやMacのようなOSの一つ。Ubunutu, Linux Mint, Red Hat, Fedora, Debian等と呼ばれるもの。これらはLinuxに分類されるものの中で、ディストリビューションと呼ばれる階層の差で名前が異なっている。


プログラミングをしたり、遠隔地にある計算機(例えば数値計算に特化した設定・設計がなされている)にログインして操作したりするときには端末(terminal, consoleとも言う)を使って作業をするのが便利。こういう用途にはLinuxが極めて向いている。

## Linuxはちょっと...という場合
Macもかなりこの用途に向いているので、既にMacに馴染みがある人には良いかも。Windowsを使う場合はWindows Subsystem for Linux (WSL) というものがあるけれど、これはそもそもLinuxを使ったことがある人向けという感じで、知らない人がここから端末操作に入門するのは難しいかも。Cygwin, mobaxterm等のエミュレーターをインストールする方が良いかも。個人的にはmobaxtermがおすすめ。

他に仮想環境に入れる方法もある。VMwareとか、Virtual BOXとか。計算を走らせると、WSLよりも断然速い というベンチマークがいくつか見つかる。

# Linuxのインストール
Red Hat以外は基本的にフリー。所望のディストリビューションの名前で検索して、ダウンロードしてくる。よくあるパターンは
1. isoファイルをダウンロード
2. isoファイルをDVD-Rに焼く
3. そのDVD-Rを起動時に読み込む
という流れ。具体的なインストール方法は探せばたくさん記事が見つかる。最初に試みるときは、消してはいけない環境では行わないこと。周りにもう使わないコンピューターを持っている人がいないか探してみて、そうした筐体を人身御供にすると良い。ハードに使わなければ、少しスペックが劣るものでも快適に使えるはず。

最初のLinuxとしてのおすすめは、Ubuntu(一番web上で情報が多い), OpenSUSEのあたり。Linux MintはUbuntuに使用感が似ていて、かつ要求スペックが低いらしく、使いやすいという話を聞く。(実際に使ったことはない)
もっと網羅的なな内容：[年収1000万円を要求するインフラエンジニアが知っておくべき最低限のLinuxディストリビューション](https://qiita.com/psycho/items/d6302aab6d23d32445c1?utm_source=Qiita%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9&utm_campaign=0fcff3d2ba-Qiita_newsletter_383_10_16_2019&utm_medium=email&utm_term=0_e44feaa081-0fcff3d2ba-34474201)



# 端末、terminal, console
テキストベースでコンピューターを操作する際の入り口。いわゆるCharacter User Interface (CUI)。Windowsで言うところのコマンドプロンプトやPower Shell。

## 先ず設定すべきこと
何かしらのエディタで`$(HOME)/.bashrc`を開いて、以下を末尾に書き足す。

```bash
alias cp="cp -i"
alias rm="rm -i"
alias mv="mv -i"
```
これで、下記のcp, rm, mvコマンドでファイルを上書きしてしまったりする際に必ずその確認が求められる。(ディストリビューションによっては、既に類似の設定が書かれていることがあるので、その場合はここはスキップ)

## 代表的なコマンド
一日に最低一回は使うやつ

```bash
ls #ファイルの情報を表示
cd #ディレクトリの移動
pwd #今いるディレクトリの情報を表示
rm #ファイルを消去
mkdir #ディレクトリを作成
mv #ファイルの移動、名前の変更
cp #ファイルのコピー
less #ファイルの中身閲覧
ps # 走っているコマンドの一覧 バグったアプリを消したい場合にIDを特定する
kill #特定のコマンドを止めるときに使う
```


## よく使うコマンド
週に一回は使うやつ

```bash
which #アプリケーションのpathを表示
df #ディスク容量の表示
top #過渡的なリソースの表示
w 
grep #文字列探索
less #ファイルの閲覧
env #環境変数の表示
man #マニュアルの表示
```

## リモート接続

```bash
ssh
sftp
rsync
```

## 覚えてるけどそれほど使わないかも

```bash
cat
head
tail
```

## シンボリックリンク
スーパーコンピューターやクラスター計算機で、`/home/username`のユーザーのディレクトリ以外に`/work/username`等の計算用ディレクトリが用意されていることがある。こういう時、毎回pathを打って`cd`するのはだるいので、シンボリックリンクをログインして最初に到達するホームディレクトリに置いておくと良い。例えば

```bash
ln -s /work/username /home/username/work
```
とすると、ホームディレクトリ(`/home/username/`)に居れば、`cd work`でworkディレクトリに移動できる。近い挙動はaliasでコマンドを定義しても、実装できる。

## 初心者脱出のためのテク

### tab補完
`cd`, `ls`のコマンドの後に入れるpathや場合によってはコマンドのオプションはtabを叩く(なぜかtabは 押す ではなく 叩く と言われる事が多い気がする)事で補完される。補完は、それ以上文字を入力しないと一意に保管内容が決まらないところまでが保管される。そこでもしつこくtabを叩くと、補完候補が端末に表示される。pathを入力したい場合はとにかく、tabを叩きまくる。

ちなみに古い環境のsftpだとtab補完ができない。Macのsftpもtab補完ができない。

### ctrlの利用
端末に入力した内容は、とある場所(bashを使っていれば`~/.bash_history`)に保存されている。したがって、同様のコマンドを使いたい場合はそれらを利用できる。例えば、カーソルキーの上下で過去の直近のコマンドが表示され、そこでEnterを叩けばそのコマンドが実行できる。

しかし、通常のキーボードではカーソルキーは遥か遠くにある。このカーソルキーの上下はそれぞれctrl + pとctrl + nで実現できる。(emacsの操作と同じ)

過去数回の履歴を探索するのでは困難な場合がある。そういう時はctrl + rで過去の履歴から文字列でヒットした順にコマンドを検索することができる。同じキーワードでもっと過去にさかのぼりたい場合は再度ctrl + rで、検索を中止したい場合はctrl + g。

### `man`コマンドの利用
コマンドには様々なオプションがつけられて、機能を調整できる。こうしたオプションはweb上で探すのが手っ取り早いが、コマンドのバージョンに依存してオプションが異なるケースがある。

こういう場合に、自身が使っているバージョンのコマンドのオプションの正確な情報を得るために`man`コマンドが必要となる。このコマンドで、実際に自走されているコマンドにおけるオプション等の情報が手に入る。例えば`man ls`で`ls`コマンドのオプションが見られる。

### ctrlキーの場所の変更
通常のキーボードでは、ctrlキーはzの左下か/キーの下あたりに用意されている。ctrlキーとの同時押しの度にここまで指を伸ばすのは極めて面倒である。こうした動機によって、(憎き)CapsLockをつぶしてctrlキーにしてしまうのが良い。どうしてもCapsLockの機能を残したい場合は、ctrlとの位置の交換にすればよい。

ディストリビューションによってはキーコンフィグの一環でこれを実現できる。また、`xmodmap`コマンドを使うことでこの目的を達成できる。

ちなみに日本語キーボードのMacではデフォルトの設定でctrlがaの左にあり、英語キーボードでも純正のキー配置変更設定でaの左にctrlを持ってくることができる。Windowsの場合はレジストリをいじるフリーソフトをインストールする必要がある。

### パイプ`|`の利用
bash等で、パイプ`|`を使うことで、複数の処理をファイルへの書き込み等を介さずにすることができるようになる。パイプでは、その左に書かれた処理の標準出力をその右に書かれた処理の標準入力に投げることができる。

例えば、`grep`でとあるファイルの中から特定の文字列を探すことを考える:

```bash
grep warning log.log
```
この時、ファイル中に`warning`の文字列が100個も200個もあると、端末は`grep`の標準出力のデータで埋まってしまう。これを端末の表示のスクロールでさかのぼって確認するのは効率的ではない。これを避けるために`grep warning log.log > warning_log.txt`などとして、ファイルに書き出してそれを閲覧することもできるが、これは余分なファイルができてしまって消すのも面倒だし`rm`コマンドはその使用にリスクが発生するので避けたいのが人情である。そこで、代わりに

```bash
grep warning log.log | less
```
として、lessに投げることで表示の結果を`less`コマンドの機能を使って閲覧することができる。
他にも以下のような使い方が考えられる

```bash
grep warning log.log | grep small # warning の文字列を含む中で small の文字列を含むもののみを取得する
grep hour log.log | tail # hour の文字列を含む中で、最後の10行を表示する
```

### タッチタイプ
特にターミナルで作業する場合。せっかくキーボードで多くの作業ができるのに、いちいちキーボードを目視で入力するキーを探していたら、意味がないので。

# パッケージマネージャー
Linuxを使う上での最も便利な点の一つがパッケージマネージャーを使ったアプリケーションの管理である。

通常、アプリケーションは依存するライブラリや他のアプリケーションがあり、これらを先んじてインストールしておく必要がある。しかし、何が何に依存しているのかを、その度に判断するのは著しく困難である。パッケージマネージャーを使うことで、こうした依存関係の情報をパッケージマネージャーに一任することができる。

パッケージマネージャーを使って特定のアプリケーションを入れようとすると、依存関係にあるアプリケーションやライブラリも同時にインストールされる。また、インストールされたアプリケーション同士の競合関係についても管理されていて、通常は排他的にインストールがされる。

また、パッケージマネージャーを通じてアプリケーションをインストールすると、path等の設定も併せて行われるため、すぐにアプリケーションが実行できる環境が整う。類似の機能として、MacのApp Store、WindowsのMicrosoft Storeがあるが、Linuxのパッケージマネージャーの方が対応しているアプリケーションは(種類が違うという点はさておき)圧倒的に多い。

ただし、パッケージマネージャーで導入されるアプリケーションとライブラリは必ずしも最新のバージョンではないことには注意が必要である。

Redhat系であれば`yum`、Debian系であれば`apt`、OpenSUSEであれば`zypper`。

# リモート接続
Linuxを使う一番の理由はリモート接続にあったりする。
通常研究室で管理している数値計算用のワークステーション、クラスター計算機はLinuxで構成されている。設置場所は居室とは限らないし、大抵は研究室単位の計算機部屋か専攻・プロジェクトの単位で管理している計算機部屋に置かれている。(こうした計算機は通常割とうるさいし、空調の管理された部屋に置いておく必要があるため。)こうした計算機で計算を流す際には、現地に行って操作するのではなく、原則リモートでアクセスして、その環境上で計算を投入する。他にも所謂スーパーコンピューターと呼ばれる大学や研究所の単位で管理された大規模な計算資源もこれと同様、リモートでアクセスして操作をする。
このアクセス先の計算機をリモート、アクセスするために手元で操作する計算機をローカルと呼ぶことが多い。

## リモート環境の操作
こうした目的に通常`ssh`なるコマンドを用いる。よく使う書式は

```bash
ssh username@192.168.xxx.yyy #ssh [user name]@[IP address]
ssh username@remote_name #ssh [user name]@[host name]
```
といった感じ。
管理している計算機にはIPアドレスが降られているので、それを指定する。研究室等の閉じた環境の中では、ルーターが外と内をつなぐ役目を果たした内部ネットワークが構築されている(に違いない)。この内部ネットワークは通常192.168.xxx.yyyといったアドレスでIPアドレスが降られているので、所望の計算機のIPアドレスを教えてもらって、それを上記のように記載する。多分事前にアカウントを作ってあるので、そのアカウント名を上記のように書く。手短にxxxとyyyについて説明すると、xxxは構成しているルーターとか計算機を管理しているポリシーで決まった(通常は)定数。内部ネットワーク内にある計算機が255台未満であれば、連番でアドレスを振ることができ、それがyyyになる。256台を超えている場合は、xxxの値も変えてより大きなネットワークを組む。
内部ネットワークにDNS(IPアドレスと計算機のホスト名を紐づける)サーバーが置かれている場合は、IPアドレス以外に、ホスト名を上記のように指定しても接続できる。ホスト名は地名だったり、アニメの登場人物だったり、神々の名前だったり、船の名前だったり。

上記のコマンドを叩くと、先ずアクセスしている計算機が本当に自分が思っているものかどうか という事を聞かれる。そして、その後にアカウントを作った際のパスワードの入力を求められるので、それを入力するとログインができる。鍵を使った認証しか認められていない場合もあって、それは[続編]()で。

## X windowを使う
リモート接続をしている際、リモートマシンのいくつかのアプリの画面を[X Window System](https://ja.wikipedia.org/wiki/X_Window_System)使うことで、こちらに飛ばすことができる。そのためにはsshで接続する際に`-X`のオプションをつける:

```
ssh -X username@192.168.xxx.yyy
```
このとき、Xをこちらに飛ばすには、ローカルマシンにX Serverがインストールされていなければならない。通常のLinuxのディストリビューションならデフォルトで入っている。Macは別途X Quartzをインストール必要がある。Windowsの場合はいろいろ方法はあるが、mobaxtermをエミュレーターとして使うのが楽。WSLで使っているlinuxディストリビューションのX serverもmobaxtermが担ってくれる。理由はわからないが、Macの場合

```
ssh -Y username@192.168.xxx.yyy
```
の方がXの振る舞いが安定。
動作確認はリモートマシンにログインした状態で

```bash
xterm
```
を叩いてみて、画面が飛んでくれば基本的な設定は正しくできているはず。

## ネットワークの設定
設定を書き換えて(GUIベースでも設定ファイル手編集でも)みても、起動している間に反映されないことが結構ある。ネットワークサービスだけの再起動も出来るけれど、結構ディストリビューション(とver.)によって、やり方が違ったりする。よくわからなかったら、再起動して確かめてみるのが良い。(プリンターとかルーターとかのネットワークもちょいちょいこういう状況に直面する)

# コードのビルド
## `configure`を使ったビルド
`hogehoge.tar.gz`といった類のファイルをダウンロードしてインストールする場合。
展開によって、通常`hogehoge`というディレクトリができるので、そのディレクトリに`cd`して、

```bash
./configure --prefix=/path/to/be/installed
make
make install
```
で、`/path/to/be/installed/`下にアプリケーションがインストールされる。`--prefix=/path/to/be/installed/`の部分を書かないと、アプリケーションでデフォルトで指定されているpathにインストールされる。この時、このpathが`/usr/bin/`等、管理者権限がなければアクセス出来ない場所にされていると、`make install`のところでコケる。自身がアクセス権を持っている所をprefix以下に指定する必要がある。

アプリケーション毎に異なるオプションがconfigureには用意されている。それらの詳細や、configureまわりについて確認したい場合は

```bash
./configure --help
```
で、確認できる。

# FAQ
いま集めている所。