続々々々々GShell

開発:さて、今日はUnix的なるものの核心の一つ、pipe に取り組もうと思います。

社長:それは標準入出力と切っても来れない関係にありますね。

開発:pipeにはファイル名がありませんからね。予めオープンされたディスクリプタとしてしか獲得できない。それは普通、shellから標準入出力として、fd0 とかfd1としてプログラムに渡されるわけです。

社長:ディスク上に記録されないので無限長のデータ処理も可能。今はマルチコアの時代なので、pipeをはさんでまさにパイプライン並列な高速処理ができるようになりました。

開発:shell のパイプ記号 | のわかりやすさもあって 、出力と入力のプログラムを並行して起動してパイプでつなげるという方式は大成功を納めたと思います。

社長:半世紀くらい前に読んだ「Unixの四半世紀」という本でも、ベル研の人たちがこれを思いついた時に大喜びしてたシーンが書かれてた記憶があります。

開発:これがベースになって、いわゆるフィルターコマンドという形で各種のコマンド部品が蓄積されて行きましたね。各プロセスは単に入力を加工して出力に出すだけなので、書きやすいし、それを組み合わせるのは外で、通常はshellがやってくれて、いろんな組み合わせができる。

基盤:まあ、cat | sort | uniq -c | sort なんてのは今でもよく使います。grep も -e とか付けるのが面倒なので、grep | grep | grep ... なんて継ぎ足していくことが多いですね。性能的にも問題無いし。

開発:ただこの、いろんな処理が一つにまとまっているのが簡便な一方、ちょっとフィルター的に収まらないプログラムを作る時に残念なことになるわけです。

社長:pipe記法の制約の一つは、a | b という記述で、a と b が同時に起動されないければいけないということだと思います。まあ、データを一気に上から下まで流すという使い方を想定すればそれで良いのですが、そうでないこともある。

開発:なので、このパイプ記法がワンセットとして実現している機能をプリミティブにばらして、ユーザがそれを組み合わせられるようにできると面白いだろうなと思うわけです。

* * *

基盤:ここで一つ、昨日入荷した桃ちゃんを頂きたいと思います。うーん、なんか香りが弱いですね。

社長:なんにしろ桃は皮ごと食べるのが常道です。ではひとくち。がりっ

基盤:あれ?めっちゃ固いですね。がりがり

開発:桃とは思えないこの食感。普通なら困ってしまうほどのジューシーさがまるで無い。ごりっ

社長:まあ、果物には当たり外れがありますけどね。しかしこれはひどい…

開発:あのスーパーは昔はこんなものを売るような店じゃなかったですが…

* * *

開発:さて、今日はちょっと地道な機能を追加していこうと思います。まず現状のまとめ。

開発:まず、which コマンドを拡充しまして、ワイルドカードが使えるようにしました

基盤:うーん、これは普通に便利。インストールされてるパッケージとかライブラリも同じようにできると良いですね。

開発:ヒットしたファイルの属性表示には、file コマンドに食わせるとかも良いかもですね。cksum とか wc とかいろいろ有り得る。まあ、xargsでやれるかも知れませんが、shellのビルトイン記法で。

社長:ワイルドカード検索した結果をフルパスでなくてコマンド名だけで出すモードも欲しいですね。その結果をまた、別のコマンドに食わせる。

開発:which は要するにfind の特殊形だと思うんです。逆に、which を表現できるようなビルトインのfindを作ると良いかなと思います。

開発:あとは、リソース使用量の表示について、ビルトインコマンドでも表示できるようにしました。

基盤:内部コマンドレベルのオーバヘッドは30マイクロ秒くらいですね。

社長:せっかくnopというコマンドを作るなら、アセンブラが使えると良いかもですね…

開発:ということで、とりあえず現状をアーカイブします。現在1175行。

開発:あともう一点。Goのビルドしたネイティブなバイナリの性能が気になっていたのですが、まあ立ち上がりについてはCからのネイティブと変わらないようです。

社長:CPUを使ってる時間はほぼ同等ですから、あとはバイナリがキャッシュにあるかどうかの違いが支配的ですね。

開発:CPUを一ミリ秒も食ってないのに起動・終了に3ミリ秒かかってしまっているのは、GShellの ForkExecとWaitのせいかも知れません。

雷:ピカドカドッカーングシャバリーン!!!

全員:びっくりしたー!

開発:確認のために、何もしない main()だけのプログラムでもはかってみましたが、同じようなものですね。

開発:確認のためにzshにて…

社長:3ミリ秒がこのMacMiniでのプロセスのfork+execの限界って感じですね。

基盤:この CPU %って、単にCPU時間を経過時間で割ったものみたいですが、便利だと思います。

開発:そうですね。というか、TIMEFMTは他のCPUと互換にします。

* * *

社長:さてみなさん、今日の昼食は昨日買ってきたとうもろこしであります。じゃーん。

開発:なんかイマイチ痩せたかんじですね。

基盤:では、レンジで。80度で5分くらいで良いですかね?

社長:もうちょっとかな?

基盤:ともかくレンジでGo!

レンジ:ゴー・・・

基盤:な、なんかめっちゃいい匂いがして来ました。

開発:ふくらむ期待・・・

レンジ:チーン

基盤:ぱかっと。あちっ、ムキムキ。あちちち。ちー。剥けました。

基盤:どれ一口。むしゃ。… ややナマっぽい。けど、うまーい!

開発:これはいけますねー。むしゃむしゃ。

社長:すばらしい。コンビニで売ってる茹でて長期保存のとは世界が違う。本物の世界ですね。むしゃむしゃ。

基盤:これは醤油をたらして焼きを加えたら最高でしょうね。

開発:ベランダに七輪を置きましょうかね。

社長:「写真の前に挿した桜の花かげに すずしく光るレモンを今日も置かう」智恵子抄はこの詩で終わってほしかった。

* * *

開発:ふぁ。あ。あー。いつの間にか、よく寝てしまいました。何かやろうと思ってた事を忘れてしまい…

基盤:スイカうまいですね。シャグ。

社長:今度は丸ごとに挑戦しますかね。

開発:外れたら悲しいですが、そこがワクワクもしますよね。

* * *

開発:それで、今朝方やってたパイプ関係の話ですが。プリミティブ的には、pipeを作る。pipeを入力とするプロセスを生成する。pipeを出力とするプロセスを生成する。これだけだと思います。

開発:たとえばこんな風になります。

社長:まあ、送る側も受け取り側も、途中で別人に交代しても悪くないのは確かですが。

開発:これで、cat a b c は必要なくなって、cat a ; cat b ; cat c でも良くなります。

基盤:猫いらず。

開発:それ次に、tee を考えます。

社長:cat は fan-in ですが tee は fan-out ですね。

開発:で、こういう風にプリミティブに分解してやると、接続関係は自習になります。メッシュ状にもループ状にも。

社長:私はそれで昔、π言語を使って接続を書きました。

基盤:端末から入力したい気はあまり起こらないですね。

開発:なにか新しい使い方が思いつくかもですよ。たとえば入力した数値を一つカウントダウンして出力するというプログラム。decとしましょう。

社長:なかなか本格的なプログラムですねw

開発:で、このプログラムの出力を自分の入力につなげてやると。

基盤:-i と -o じゃなくて < と > になったんですね。

開発:まあ、どっちでもいいんですが。脳内に刻まれてしまった特殊記号には勝てないですね。一文字だし。

社長:なんにしても、普通の shell では書けないことのようには思われます。

開発:namedpipe で出来るとは思いますけどね。

社長:socketpair なら双方向に通信できるから、何か面白いことができるかもですね。

開発:まあいずれにしても、標準入力を処理して標準出力に出すというある意味無敵な汎用モデルには勝てないですけどね。ただ、フィードバックループを持つプログラムは普通にありますから、それをshellでサポートしてコマンドレベルで部品にできれば意味があるようにも思います。

社長:標準制御入力とか標準ログ出力とかもあってよいですよね。要は、入力をselectしてどこからデータが来たらどうする、というのがプログラムの標準モデルとして提供されていないのが問題な気がします。

開発:そのへんは当然シミュレーション用の言語とかではあるわけですから、それをそのままshellに持ち込むでも良いかもですね。

社長:私が学生の時の研究室が貧しくて、シミュレーション用の言語の処理系が買えなかったんです。だもんでSimulaのサブセットを自分で付くて使ったりしてました。

基盤:コロナでお亡くなりになってしまった方ですね。

* * *

社長:ところで、どうも気に入った壁掛け時計が無いんで、自作したいなと思うんですが。

基盤:気温とか、電力消費とかも表示すると良いですね。

社長:いつものデスクトップに表示するのは、ちょっと違うかなと思うわけです。

開発:なんてったって憧れるのは電光掲示板ですよね。やはりLEDの発光には魅入られます。小さいのなら 3000円位で手に入るみたいですが。こういうの。

開発:ラズパイで制御したいと思います。

社長:64 x 32 ってことは、ちっちゃいアイコンの情報量ですね。

基盤:ちっちゃいLCDモニタなら5000円くらいでありますよね。ああ、HDMIで7インチ3000円近辺がふつうみたいですが。

社長:そういうの、前の職場で使ってましたが、普通に良かったです。LEDにしましょう。

基盤:タッチパネル機能付きで7000円のもありますね。ラズパイ愛好者にオススメ。

開発:その写真の手の人はコビトさんですかね?

社長:これにしましょう。

経理:溜まってるアマゾンポイント全投入します。ぽちっ。金曜日にお届けとのこと。

基盤:楽しみ!

社長:今気づいたんですが、今日は水曜日なんですね。昨日は月曜だと思っってボウリングの試合に出かけたのですが…

開発:どこかで一日タイムスリップしたようです。

基盤:ブログに空白日は無いようですが…

社長:試合を休んでチームに迷惑をかけてしまいました。今たぶん、2位につけているはずなのですが…

* * *

社長:ところで、gshell から簡単に unfs3 を起動できると良いですね。listen localhost:9999 repeat accept unfs3 / $HOME/public-nfs/ みたいな感じで。

開発:unfs3 から GShell の内部状態を見れないと面白くないですね。まだ GoでCプログラムと動的リンクをやってみたことはありませんが…

社長:外部プログラムを起動するのに3ミリ秒かかってしまうようですし、やはり頻繁に使ったり高速な応答が必要な「外部コマンド」は動的リンクして実行する必要があると思います。

開発:考えてみればタイムスリッパでGoのgettimeofday()を簡単に入れ替えられたわけですから、あれと同じですよね。exec() をすり替えるとかですかね…明日トライしましょう。とりあえず今日はここまでで。

-- 2020-0812 SatoxITS