知り合いに頼まれて、ちょっとUNIXの初歩を教える授業をした。
ちょっとといっても結構がっつりで、入ってきたばかりの、だいたいは家にパソコンがないという素人の学生に、2ヶ月間・23日・2コマずつで基本を教え、ちょっとしたツールをシェルスクリプトで作れるような、いわば普通のUNIX使いにしてくれ、という要望である。
一応の教科書は指定されたのだが、自分で買って読んでみたところ、あまり良くなかったので使わなかった。「これはリファレンスに使ってください」ということにした。
代わりに使ったのは、自分が真に優れていると思う本、Kernighan & Pikeの『UNIXプログラミング環境』である。1984年初版、対象はVersion7 UNIXと非常に古いので、内容は全部作り直しだ。全9章あるが、Cでツールを作り出す6章以降はいらないし(9章なんてtroffの詳細だぜ)、5章で作るツールはかなり古臭いので、ここは考え方や用法を使うのみ。実質的にはawkの魔法を見せる4章までである。
それでも200ページほどの内容を現代的に組み直す必要があった。古い部分を捨てたり、新しいもので置き換えたり(bashすげえ)、gitのようにまったく違う体系を組み込んだりして、毎回の資料を作っていった。
まったく条件が違う部分もあって、たとえば学生は1人1台のLinuxノートPCを使っており、VAXやテレタイプ端末やTSS端末は使われていない。多人数で同じマシンを使うことがないから、他のユーザーのログインしてくる様子をうかがうような部分は使えないし、ユーザー間のコミュニケーションも行われない。キーボードも現代のパソコンのものなので、2日目の授業ではCapsLockをCtrlに置き換える作業をさせ、Ctrl-?で操作する体系を教えた。デバイスもファイルであることを示すのは
cat /dev/input/mouse0 | od
をやらせた。
補った部分もある。『UNIXプログラミング環境』ではさらっと触れられているだけの、シェルのコマンドライン解釈順序などは、ソースを調べて詳細に解説する必要があった。ディレクトリのパーミッションの詳細も、ソース以外に解説がなかった。
そんなこんなで、作業量は膨大だし、進行に合わせて組み直すので、最後まで非常に大変だった。午前中に授業、午後に翌日の構想をして必要な情報をDynalistに書き下し、翌日の朝4時からKeynoteに落として8時すぎに家を出る…などということを毎週やっていた。ひどい自転車操業である。しかしまあ、おおむね良い授業になったと思う。
全体的な雑感を書いておく:
- 手を動かさせないと寝る。
- 進行が速いと付いてこられない学生が寝る。遅いと出来る学生が寝る。
- 復習回では対象の学生ほど寝る。
学生は高校を出たての若者がほとんどなので寝る。若いということは、睡眠時間が多く必要であるということであり、また、眠くなる時間が遅くにずれるということだ。だからこれは朝9時半という授業開始時間が早すぎるのであって、学生のせいではない。11時くらいからやりたいのだが、普通の学校はそうはなっていない。わりに困る。
復習は何度か入れた。おさらいをするのは、基本のできてない学生のために、同じことをもう一度繰り返しているつもりだった。しかし、進行速度は出来ている学生があまり退屈になってもいけないので、速めになる傾向がある。そうすると意図していなかった事が起きる。
わかっていない学生ほど寝るのだ。
逆に、できてる学生の方が「あっ、ここ落ちてた!」と食いついてくる。
つまりはどうなるかと言うと、クラス内の格差を縮めるつもりでやった復習授業が、格差を広げることに繋がるのである。
すげえ難しい。
プログラムは意図した通りには動かず、書いたとおりに動く。
学生も、こちらが意図した通りには学習しない。与えられた条件に反応して学習する(または、しない)だけなのである。
伸びられる学生には立ち止まらずに思い切り伸びてほしいし、遅い学生もきっちり拾っていきたいのだが、おおむねその中間の中途半端な線を行くしかない。ここには改善の余地がある。
さて、いまは最後の試験の採点中である。コンピュータ分野の「プログラムを作って問題を解決する問題」には、こちらの意図とまったく違った回答が来るのが楽しい。
こうした試験で、教えた内容がどれだけ入っているかの確認を取るのはなかなか難しい。こちらの用意したハードルは飛んでくれず、自分で作ったハードルを飛び越えてくるのだ:
- あまり使われない、こちらが知らない機能を使って解決してくる学生がいる。正規表現を工夫させようと思ったsedの置換問題で、sedのsコマンドの数字フラグを使って置換位置を指定して解決した学生がいる。すごいじゃん。
- 問題文の隙を突いて「仕様は満たすけど、それは無いだろw」という回答を書いてくる学生もいる。同じsedの問題で、「置換前文字列」を「置換後文字列」に丸々置き換えた学生と、全部削除してechoし直した学生がいた。なるほど1行だけを書き換えるのに、正規表現を抽象化する意味はないですよねw
- 意図とは違うものの、これまでに教えたことをしっかり使い、よりシンプルな解を書いてくる学生もいる。
最後の話はこうである。awkを使って英文テキストの中の単語の文字数の統計をとらせる問題を出した。これは行の中でループを回し、各単語のlength()を配列に入れ、最後にプリントすればよい。
と思ったのだが、trにより単語間のスペースを改行に変換することで1行1単語のストリームを作り、それをawk '{print length()}' にかけることで1行1数字のストリームにして、これをsort | uniq -c | sortすることで、答えを出してきた学生が多数いる。
問題をより広い視点で捉えた上で、awkを使う、という仕様も満たしているではないか。きわめて優秀!!!である。
そして、こういうのを見ていると、多くの学生が「普通のUNIX使い」になった気がする。問題を広い視点で捉え、解決のみにフォーカスして答案を書いてくるというのは、シェルスクリプトで道具を自作するような授業の意図に、よく応じている。
授業でも「動くものが正解。最適化は後から計測してやれ」と教えてきたので、多くの答案には良い成績をつけた(まあ、動かないのを貼ってくる学生もおりますが)。
教える者が教えられる、という言葉があるが、本当にその通りである。ものすごく勉強になった2ヶ月間でした。
謝辞
ソースを調べて厳密な仕様を知りたいときに瑞慶覧辰さんに一方ならぬお世話になった。bashなどの新しいプログラムは地味にたいへん機能豊富で、かつ安全な書き方がしてあるために行数が膨大だ。それで、短く簡潔なVersion 6やVersion 7のソースを参考にしていたところ、昔のCで書かれたシステムはシステムで、行数こそ短いものの、簡潔極まりない書き方で変数も略号だらけ、処理を追うのが大変で持て余すことが多かった。そこに瑞慶覧さんが「どれどれ?」とやって来て、一瞬で理解してささーっと解説してくださるという月光仮面ぶり。すごいハッカーとは聞いていたが、目もくらまんばかりの実力を目の当たりにして感動した。ありがとうございます!
参考文献
授業をするにあたって下敷きにした本や読み返した本、さらには読み聞かせした本を参考文献として挙げておく。
Kernighan, Brian W. and Pike, Rob . 1984. UNIXプログラミング環境 石田晴久監訳 1985.
UNIXの考え方を知るのに、これに勝る本は無いと思う。こちらは85年に出たASCII版(2冊持ってるw)。
こちらは上記の新版。内容は変わっていない。新品を買いたい人に。
竹内郁雄. 2017. プログラミング道への招待
チューリング完全を教える際に、Ritchieのwhile言語について、この本から孫引きした。他にもいろいろ参考にした部分がある。
Lions, John. 1976. Lions' Commentary on UNIX 岩本 信一訳 1997
夜中にはなぜかこれを読んでいた。
上田ら 2021. シェル・ワンライナー160本ノック
この本はツールの使い方がオーソドックスで、よい用例が多い。
Graham, Paul. 2004. Hackers and Painters 川井史朗訳 2005.
ここで挙げたのは、内容を使用したか、授業の方向性に影響を与えた文献である。ほかにもJoel on SoftwareやSICP、『ライト、ついてますか』『揚げて炙ってわかるコンピュータのしくみ』などを用意したが、実際に使うには至らなかった。これらも使いたいものである。
改版履歴
2022-07-01 初版
2022-07-02 構成を少し変えて加筆