「UNIXという考え方」読書メモ


# まえおき
以前、初めて業務の中でシェルスクリプトを使い効率化ツールを作った↓
[シェルスクリプトでスキャフォールドツール作った話](https://qiita.com/michida/items/dd186a73782c0b0aabf0)

チームメンバーにも展開し使用してもらうことも出来て割と好評だった。
ただ作る上で迷いが生じた部分がいくつかあり、感覚的にそこは進めていったのだが、その解がこの本の中に書かれていた。更にこの本を読みながら思ったのは、平成13年に発行されたものとは思えなかった。
と言うのも約20年経った現在でも通じることばかりが書かれており、やはりこう言う思想や哲学という部分は何年経っても根底にあり続けるのだなと感じた。

# お気に入りの一節
ここからはお気に入りの一説を抜粋していく。

> - 小さなプログラムは、分かりやすい。分かりやすいと保守も容易になる。プログラムを理解するのが保守の第一歩だ。 p18
>
> - シンプルであるために簡単に書け、理解しやすく保守しやすい。人間にとってもマシンにとっても優しいのが小さいプログラムだ。さらに重要なことは、作った時には予測できなかったことに対しても、小さなプログラムなら直ちにそれを対処できるということだ。p22
> 
> - 平均的な学習曲線は、平坦に伸びていて徐々に急激な傾きになっていく。現代社会には生涯を持ってしても完全な知識など得ることができないような専門分野が多くある。p29

# UNIXという考え方における9つの定理

1 . スモール・イズ・ビューティフル

>   - プログラムを書くときは小さなものから始めて、それを小さなままに保っておく。
    (中略)
    一つの巨大なプログラムにしようとする誘惑に負けないで、シンプルさを追求する。p14
>
>   - 小さなプログラムを単独では大したことはできない。ほんのひとつかふたつの機能を実行するだけだ。しかし、様々に組み合わせることで、真のパワーを発揮する。
    (中略)
    プログラムをコマンドラインから入力するだけで、新しいアプリケーションを書くことさえできる。p16

2 . 一つのプログラムには一つのことをうまくやらせる

>    開発者はそのコードが本当に必要なのかどうかを常に意識しておくべきだ。p24
>    
>    以下、参考になるチェックリスト。
>    - プログラムはユーザーとの会話を必要とするのか? パラメーターをファイルから読み込む、またはコマンドラインから入力するだけではいけないのか?
>    
>    - プログラムの入力データが特殊フォーマットである必要があるのか? フォーマットを変換できるプログラムが、すでにシステム上にあるのではないか?
>    
>    - プログラムの出力データが、特殊フォーマットである必要があるのか? 通常のASCIIファイルではだめなのか?
>    
>    - 新しいプログラムを書かずとも、似たような機能を持った他のプログラムがあるのではないか?

3 . できるだけ早く試作を作成する

>   - 「できるだけ早く」とは「本当にできるだけ早く」ということだ。「大至急だ」アプリケーションの立案に少しの時間を掛け、あとはまっしぐらに進むだけだ。
    (中略)
>    あるアイデアが物になりそうかどうか目に見える現実的な場面でテストするには試作が一番だ。試作以前のアイデアは、これはこう動くはずだという憶測の域を出ない。 この時点では設計構想はほとんど理解されておらず、おそらく人によって解釈が異なっているだろう。 プロジェクトの前進には、全員の合意が必要だ。試作は具体的に目標を示すことで全員の合意を醸成する。 p31

4 . 効率より移植性

> - 多くの UNIX プログラマーが冒す間違いの一つに、わずかな速度を求めてシェルスクリプト をC言語で書き直すというものがある。 それは、時間の無駄だ。そのような時間は、ユーザーからの建設的な反応を得ることに費やした方がいい。 p51
>   
> - 新しいハードウェアに移植しやすいコードは、ハードウェアの特殊機能を利用していることよりも、ずっと大きな価値がある。p57

5 . 数値データはASCIIフラットファイルに保存する

>  - ASCIIテキストは共通の交換形式だ。p58
>
>  - ASCIIテキストは、最良の形式ではないまでも間違いなく最も一般的な形式だ 。p58
>  
>  - ASCII テキストを使う有り難みは、アプリケーションを新しいアーキテクチャに移植する時に分かる。プログラムを移植可能にするという先見の明があれば、 それとともにデータをASCII テキストにすることで、データをプログラム同様の新しいハードウェアに移すことが非常に簡単になる。p61

6 . ソフトウェアの梃子を有効に活用する

>  - 良いプログラマは良いコードを書く。偉大なプログラマは良いコードを借りてくる。ソフトウェアを大量に書く一番良い方法は、借りてくることだ。p69
>  
>  - 顧客が知りたがっているのはそのソフトウェアで仕事がこなせるかどうかということだけだ。何ができるかが大事であってどうやってそれをやるのかは二の次だ。p70
>  
>  - 全てを自動化する p75
>  
>  - コンピューターにできることを人間が手作業で行うのは時間の無駄だ。p75
>  
>  - ハードコピーをよく使っていないか？p75
>  
>  - データのソートや行数あるいはオブジェクト数のカウントを手作業で行っていないか？p75
>  
>  - システム上のファイルはどうやって見つけているか？ディレクトリを一つずつ覗いていないか？p75
>  
>  - ファイルの中から特定項目を見つけ出そうとする時ファイルを手作業で検索し、目に頼って目的の場所へ行こうとしていないか？p75
>  
>  - コマンドインタープリタに履歴機能がある時それを利用しているか？p75
>  
>  - 複数ウィンドウを表示できるワークステーションなのにいつもひとつしかウィンドウ開いていないということはないか？p76
>  
>  - マウスを使っているか？　切り貼り機能をよく使っているか？ p76
>  
>  - 使っているコマンドインタープリタにはコマンドやファイルの補完機能があるか？それを使ってキーストロークを省略して入力をスピードアップしているか？p76

7 . シェルスクリプトを使うことで梃子の効果と移植性を高める

> - Shell Script には恐ろしいほどの梃子の効果がある p78
> 
> - シェルスクリプトは、ソフトウェアの梃子の効果を高めるための最適なツールだ。
  (中略)
  このアプローチでは簡単なプログラムも書けないプログラマも含め、全員が勝者になれる。p85

8 . 過度の対話的インタフェースを避ける

> - UNIXの長所の一つは、プログラム同士が効果的に対話することにある。
    (中略)
    ソフトウェアは、人間との意思疎通を前提に作られたソフトウェアよりはるかに柔軟性がある。p95

> - 拘束的ユーザーインターフェースはスケーラビリティに欠ける p96

9 . すべてのプログラムをフィルタにする

> - コンピューターの出現以来、書かれてきたすべてのプログラムはフィルタだ。p98

### さらなる10のUNIXの考え方

1. 好みに応じて自分で環境を調整できるようにする

> - 人は、大きな投資をすればするほど、その結果に大きな関心を持つようになる。p107

2 . オペレーティングシステムのカーネルを小さく軽くする

> - カーネルが小さくて軽ければ、タスク開始時にコピーもしくは変更するデータ構造体の数が少なくてすみ、ユーザー空間でタスクが速やかに実行できる。p108

3 . 小文字を使い、短く(正直ここら辺の話はよくわからなかった。。)

> - 小文字は目に優しい。p109
> 
> - 小文字の方が変化に富んでいる。p109
> 
> - 大文字は、普通、特に注意の引きたいものの名前に使われる。例えばディレクトリの中に README という名前のファイルを置くなど p109

4 . 森林を守る(ここも正直よくわからん)

> - データを紙に印刷してしまうと並べ替えも、移動も、フィルタ処理も、変形も、修正もできない。p111
> 
> - 紙には気を付けることだ。p112

5 . 沈黙は金

> - UNIXコマンドはフィルタとして機能し、UNIXのパイプ機構によって他のフィルタと結合される。
    (中略)
    UNIXにおいては、言うべきことだけを言うのが重要だ。それ以上でも、それ以下でもいけない。p114

ここは、シェルスクリプトを作るときに迷いが生じた部分の解答を貰えたところでもある。
自分が作成したスクリプトは成功時にも成功メッセージを出力していたのだが、作成している時に出力するべきなのか何も出力しなくて良いのか迷ったが、そのときはユーザフレンドリに成功メッセージを出すようにした。結果的に利用ケースを考えれば、そのスクリプトはそれで良かったかもしれないが、今後はスクリプトを連携させる場合もあると言うことを考えながら作ることにする。ハンターハンターにもありますよね。正解は沈(ry

6 . 平行して考える

> - UNIXで並行して考えるという場合は、それはCPUをできるだけ忙しく働かせておくことを意味する。p114
> 
> - UNIXでは、複数のプロセスを同時に実行する方式を採用している。各プロセスがタスク全体の一部分を受け持つようにスケジュールしておけば、例え一つのプロセスに周辺装置待ちが入っても、その間に他のプロセスを進めておくことができる。この結果、効率は素晴らしく良くなる。p114

7 . 部分の総和は全体よりも大きい

> - UNIX的なアプローチは、統合アプリケーションを小さな部品の集まりとして構成する。この方法なら必要な機能だけを読み込める。p116

8 . 90パーセントの解を目指す

> - 一流のUNIXソフトウェア開発者がアプリケーションプログラムを設計するとき、いわば「最小費用で最大効果の上がる」解決策を見つけようとする。具体的には、あまり使われそうにない機能や、実装するには費用がかかりすぎる機能をどんどん切り捨てる。p119

9 . 劣るほうが優れている
感じたこと特になし

10 . 階層的に考える
感じたこと特になし

# 面白い一説

> - クストーのレイク・フライ。この虫たちはその生涯において一つの事をなし、成功している。UNIX の開発者は、ソフトウェアも同じであるべきだと考えている 。p23
> ナイル川のレイク・フライにできることが、人間にできないはずはない。p26

> - 動かせないデータは死んだデータだ。p58

> - これを書いている時点で来年のマシンの計算パワーの増大ぶりは、今日の ASCII テキストファイルによる余計な処理時間を埋めるには十分すぎるようだ。言い換えると現在のアプリケーションがかろうじて問題ない性能で動作をしているのであれば、明日にはスピードは十分なものになっているだろう。2、3年後には少しスピードを落とさないと人間の手には負えなくなるかもしれない。 p62

> - あるソフトウェア技術者のことを思い出す。とても一流とは言えないプログラマーで「紙袋から抜け出すプログラムも書けない」とからかわれていたものだ。しかし、小さなプログラムをいくつもつなぎ合わせるコツを心得ていた。
(中略)
実のところ彼自身は基本的なソートルーチンさえ満足に書くことはできなかった。それにも関わらず使用できるリソースを徹底的に利用して彼は大変な成功を収めたのだった。

# まとめ
ページ数としては148ページととても薄いが取っ付きにくそうだなーと感じていた。ただLinuxに興味を持ちLinux教科書という書籍や先でも書いた通りシェルスクリプトを書いてみたりして興味が湧いてきたところで、同僚からの勧めもあり読んでみると、重要なことが沢山書かれており業務にも通じる設計思想を固めることができた。気になっている人などは是非読んで見て欲しい。

[UNIXという考え方―その設計思想と哲学](https://www.amazon.co.jp/UNIXという考え方―その設計思想と哲学-Mike-Gancarz/dp/4274064069)