Missing Semester IAP 2020 まとめ【随時更新】

はじめに

YouTubeのMITの補講みたいな授業
Missing Semester IAP 2020の内容を適宜まとめていきます><

Lecture 1 Shell

シェル

パソコンと対話するCLIにターミナルが存在し,ターミナルの内部ではシェルを使って対話を行っている.

シェルでは,コマンドを打つことで

  • ターミナルがコマンドを標準入力から受け取る
  • シェルが解読,カーネルへ解析内容を送信
  • カーネルが処理を実行
  • シェルが結果を受けたりターミナルが画面に表示する

という流れになっている.

環境変数

普通のプログラミング言語と同様にシェルにも環境変数が存在する.
代表的なものは$PATHである.

シェル変数とは異なるので注意><

標準入出力

通常標準入出力はキーボードと画面だが
ファイル入力や他のコマンドへの出力ができる.

<を用いることで,リダイレクトができ,標準入力を変更できる.
同様に>を用いることで,標準出力を変更できる.
|パイプを用いることで,他のコマンドの標準出力を,他のコマンドの標準入力として取り入れることができる.
接着剤みたいなイメージ.

Lecture 2 Shell Tools and Scripting

Shell Scripting

毎回シェルでコマンドを書くのは面倒.
そのため,シェルではループや変数など,プログラミング言語っぽく処理ができ
ファイルに関数や処理を書いておくことで,繰り返し利用することができる.

(普段僕はfishなので,bash, zshのは読めません・・・)

変数

シェル変数は

foo=bar  
echo $foo  

のように初期化はドルマークを付けず,変数としてはドルマークをつける.

Bashなどのシェルでは,””のダブルクオートなら,"$foo"を展開してくれる.

関数

関数は,hello.shのようにシェルスクリプトを定義し

mcd () {  
    mkdir -p "$1"  
    cd "$1"  
}  

のように定義すればよい.

特殊変数

bashなどのシェルでは,特殊な内容を表すすでに定義された変数が存在する.

  • $0: スクリプトの名前
  • $1~: 引数
  • $@: すべての引数
  • $#: 引数の個数
  • $$: プロセス
  • !!: 前回のコマンド

などがある,

シェルスクリプト

#!/bin/bash  

echo "Starting program at $(date)" # Date will be substituted  

echo "Running program $0 with $# arguments with pid $$"  

for file in $@; do  
    grep foobar $file > /dev/null 2> /dev/null  
    # When pattern is not found, grep has exit status 1  
    # We redirect STDOUT and STDERR to a null register since we do not care about them  
    if [[ $? -ne 0 ]]; then  
        echo "File $file does not have any foobar, adding one"  
        echo "# foobar" >> "$file"  
    fi  
done  

一行目に,何を実行するか書く.
これによって,シェルの種類を指定しなくても自動でそのシェルで実行してくれる.

ただし,コンピュータによって,このシェルの位置やPythonのいちが異なる.

そのため,

#!/usr/bin/env python  

のようにすることで,envコマンドを実行し,pythonなどの位置を割り出して,それで実行してくれる

findとgrep

findコマンドはファイル名で再帰的に検索
grepコマンドは中身で検索してくれる

便利コマンド

tldrこれすごい便利でした
man lsだと長すぎるので,要点だけを取り出せる.

broot treeのインタラクティブ版,探しやすいです><

nnn 検索のインタラクティブ版,IDEっぽい

Lecture 3 Vim

Vimの思想

プログラミングのほとんどの時間を,多くの人間は書くことではなく
「読むこと」と「編集する」ことに時間を費やす.
そのため,Vimはプログラミング言語として,操作をプログラミングでき,マウスを使わずして,簡単に操作できるようにしている.

Vimのカスタマイズ

Vimは~/.vimrcの設定ファイルに書くことで,より人それぞれにあった自分だけのVimを育てられる.

また,プラグインを用いることでさらに自分だけのVimを育てることができる.

Vim-mode

Vimはキーバインドとして優秀なので,シェルや多くのIDEでVim-modeを持っている.

fishにもあるのでうれしい!
また,Chromeなどブラウザにもあるのでぜひ使おう!

20時間使うと,プログラマは新しい概念を知り始め
そこから先は「学習」よりも効率良い結果が得られる.
そのため,どんどん新しいことを学習していこう.

4 Data Wrangling

Data Wranglingとは,データを取得したときにより使いやすいように加工すること!日本語だと前処理に近い.

sed

sedは,標準入力から受け取ったデータを加工して
標準出力に出すコマンド.

sed 's/.*Disconnected from //'
などとすることで,正規表現などを扱うことができる.

正規表現

テキストをより効率的に処理するための記法.
今度Youtubeで学習する.

awk

sedと同じプログラミング言語の一つ.
sedは置換に主に用いて,awkはどちらかというと抽出や区切り文字で利用する.

sed, awk, 普通のコマンドをパイプを大量に用いることで
使いやすいデータを取り出そう!

リンク

5. Command Line Environment

Job Control

プロセス(ジョブ)を実行しているとき、それらを中断したい場合や
一時停止したい場合が存在する。

これらのプロセスに対する要望に答えるために
signalが多く定義されており、ターミナル上のキーボードにマッピングされている。

シグナルとは、プロセスとプロセスの間で使われる信号であり、この信号を受け取るとプロセスは規定の挙動を起こす。

シグナルには多くの種類が存在し、それぞれキーボードバインドと、その名前、規定動作が定まっている。

たとえば、SIGINT(SignalInterrupt)は、信号を受け取るとそこで実行を終了する。
Pythonなどでは、このCtrl+Cを受け取ったときにエラーハンドリングすることで、もみ消すこともできる。

#!/usr/bin/env python  
import signal, time  

def handler(signum, time):  
    print("\nI got a SIGINT, but I am not stopping")  

signal.signal(signal.SIGINT, handler)  
i = 0  
while True:  
    time.sleep(.1)  
    print("\r{}".format(i), end="")  
    i += 1  

ただし、SIGKILLのみは再定義できない。

ターミナルを終了するとSIGHUPで、そのターミナル(シェル)から生成したプロセスが終了してしまう。
そのため、nohupを使って、プロセスがSIGHUPを受け取らないようにして実行を継続させる。

Terminal Multiplexers

ターミナル多重化。
tmuxなどのアプリで、セッションごと管理してしまう。

  • セッション
    • ウィンドウ 一つの仮想端末の画面
      • ペイン ペインごとに独立した擬似端末

の構造になっており、複数のセッションを管理できるので
途中で終了してしまったり、他の環境から同様のセッションを使用できる。

ただ、iTermを使っているとペインが存在しているのでいらないような気もする(多分tmuxのほうが楽なんだろうが・・・ ちょっと色々と触ってみてから判断)

Dotfiles

ターミナルやVim、tmux, itermなどの設定ファイルはドットから始まるファイルで管理されている。
これらのファイルをDotfilesという名前でGitで管理することが多い。

育てていく、という感じ。
作らないとなぁ・・・

Remote Machines

SSHで遠くの端末に接続できる。
このとき、sshでは公開鍵や秘密鍵を使うと毎回パスワードしなくていいので楽。

~/.ssh/config

Host vm  
    User foobar  
    HostName 172.16.174.141  
    Port 2222  
    IdentityFile ~/.ssh/id_ed25519  
    LocalForward 9999 localhost:8888  

# Configs can also take wildcards  
Host *.mit.edu  
    User foobaz  

こういうのを書くと、ssh vmで接続できるので楽でうれしい

感想

Dotfilesは育てていこう・・・><
いい加減、毎回コピーするのがつらい・・・

6 Git

データモデル

Gitは、ファイルをblob
ディレクトリをtreeとして管理して、DAGとして管理している。

各要素をハッシュ化して、名前と対応付けている。

Basics

  • git help <command>: get help for a git command
  • git init: creates a new git repo, with data stored in the .git directory
  • git status: tells you what's going on
  • git add <filename>: adds files to staging area
  • git commit: creates a new commit
  • git log: shows a flattened log of history
  • git log --all --graph --decorate: visualizes history as a DAG
  • git diff <filename>: show differences since the last commit
  • git diff <revision> <filename>: shows differences in a file between snapshots
  • git checkout <revision>: updates HEAD and current branch

Branching and merging

  • git branch: shows branches
  • git branch <name>: creates a branch
  • git checkout -b <name>: creates a branch and switches to it
    • same as git branch <name>; git checkout <name>
  • git merge <revision>: merges into current branch
  • git mergetool: use a fancy tool to help resolve merge conflicts
  • git rebase: rebase set of patches onto a new base

Remotes

  • git remote: list remotes
  • git remote add <name> <url>: add a remote
  • git push <remote> <local branch>:<remote branch>: send objects to remote, and update remote reference
  • git branch --set-upstream-to=<remote>/<remote branch>: set up correspondence between local and remote branch
  • git fetch: retrieve objects/references from a remote
  • git pull: same as git fetch; git merge
  • git clone: download repository from remote

Undo

  • git commit --amend: edit a commit's contents/message
  • git reset HEAD <file>: unstage a file
  • git checkout -- <file>: discard changes

Advanced Git

  • git config: Git is highly customizable
  • git clone --shallow: clone without entire version history
  • git add -p: interactive staging
  • git rebase -i: interactive rebasing
  • git blame: show who last edited which line
  • git stash: temporarily remove modifications to working directory
  • git bisect: binary search history (e.g. for regressions)
  • .gitignore: specify intentionally untracked files to ignore

8. Metaprogramming

ビルドシステム

LaTeXや、他のアプリなど
各OSやマシンごとに、直接ビルドを行う場合がある。
直接ビルドをすることで、よりそのOSやマシンにあったコードに最適化して、効率的な処理を行うことができる。

そのとき、ビルドのコードを統一化するために、ビルドシステムが用いられ、例えばmakeがある。

Makefileに

  • 処理の名前
  • 処理で扱うファイル群名
  • そのときに実行するコマンド

を書くことで、これらを自動実行してくれる。
さらに、内部でファイルが更新されたかをチェックし、ファイルが変更されるまで同じ処理を繰り返さないようになっている。

参考サイト

依存管理

ライブラリなど、プログラミングでは多くのソフトウェアが互いに依存しあてってできている。
そのため、勝手にバージョンを変更したり、不一致になると、処理がうまく動かなくなってしまう。

そこで、semantics versioningを用いて、プログラムは更新を行う。

主なバージョン.セミバージョン.パッチ番号のようになっており
例えばPython3.5.4などは

3というメジャー番号であり、セミバージョンは5、その中で細かい修正は4回め、という意味である。

メジャー番号は、後方互換性を保持しない破壊的なものであることが多く、このバージョン差には気をつける必要がある。
次に、セミバージョンは、機能を追加する場合に使用し、上げる文には基本的には問題ない。
パッチ番号は、外部への関数の呼び出しや変数などは変化させず、内部のバグ修正やセキュリティ修正のみに用いられる。

これらのバージョンを保持したpackage.lockファイルなど
バージョンを記したファイルなどを用いることで、公開する際はバージョンを指定しても良い。

9. Security and Cryptography

Entropy

エントロピーは、ラムダムネスの指標であり、この値が大きいほどパスワードとしての強さが示せる。

log2()でエントロピーを計算する。

例えば、コインの裏表はlog(2) = 1であり
サイコロならlog(6) = 2.xぐらいである。

ハッシュ関数

ハッシュ関数は、バイト列を受けとってある固定の長さのバイト列に変換する。
大事な特徴として

  • 決定的である(同じバイト列を受け取ったらある特定のバイト列を出力する 、確率的でない)
  • 出力値から入力値をすいそくできない(全探索するしか無い)
  • ある出力値になるような複数の入力値を発見できない(発見はできるが、天文学的に難しい)
  • ある2つの要素を選んだとき、出力値として一緒になることが非常に難しい

というもの。

Symmetric cryptography

keygen() -> key  
encrypt(plaintext, key) -> ciphertext  
decrypt(ciphertext, key) -> plaintext  

上記で表される対照的暗号化。
Keyを用いることで、暗号文を作り、その暗号文に対してKeywo用いることで復元できる。

Keyは、覚えるのが難しいので通常はkeygenにパスフレーズを入れてKeyを生成する。これによって、パスフレーズのみ覚えていればいい。
秘密鍵暗号に相当し、高速かつ計算量が小さい。

ウェブなどで用いる場合はsalt(ソルト)という、各サイトごとにランダム列を作って組合せて使う。
ソルトを用いないと、同じ暗号化アルゴリズムを使っている複数のサイトにおいて、あるサイトで暗号化されたパスワードが発見されると、元のパスワードが復元されたときに他のすべてのサイトをトッpされてしまう。
塩を用いることで、見た目上防げる。

Asymmetric cryptography

非対称暗号化。
公開鍵暗号方式。

秘密鍵だけ自分が持っていれば、相手が公開鍵で暗号化したものを自分は秘密鍵で解読するだけでいい。
また、署名にも使う。

署名では自分が秘密鍵で暗号化し、それを相手が公開鍵で解読することで本人であることが示せる。

公開鍵暗号は重いので、内部で秘密鍵と併用する
ハイブリッド暗号方式として使うことが多い