cut 比べ
結城さんの本を苦労しながら読んでいる。球面幾何。普通の頭では意味不。脳に汗をかきながらね。巻末に参考資料が紹介されていた。
以前、ここに来た事あるぞ。確かipadに入れて読んだ記憶がある。調べてみたら2012版のものが入っていた。
それから幾年月。加筆訂正されて、更にはPDF内をあちこち飛び回れるようにリンクが縦横無尽に貼られている。ぼけた頭には嬉しい機能。そして年寄り向きに、拡大フォント版も用意されてる。図書館にある弱視用の本の作りだ。これはもう、最初からじっくり取り組むしか。
売られている電子書籍でも、索引が付いていなかったり、あちこちに飛べなかったりの粗悪品が沢山あるそうな。あの人が嘆いていた。彼の眼にはこのPDFはどう映るのかねぇ、是非聞いてみたいぞ。
会社を定年退職した元同僚と、たまには連絡してるんだけど、彼は分子工学とかにはまって、頭を捻っているらしい。大人の自由研究、大いに結構じゃないですか。
不幸は続く
メインで使ってるWindows10機が、この所不調。前回は、IMEが早とちり症候群に侵されて、どうしようもなく、WSLなんてのに走ってしまった。
今は、マウスが奔放に走り回ってしまい、手に負えない。マウスのポインターを見失ってしまうので、年寄り向きの大マウスポインターに切り替えた。これで少しは、何処にいるか分かり易くなるだろう。
不幸は続いてやってくる。突然にね。 試しで入れているVMWare上のUbuntuが起動しなくなった。
小さいコンソールなんで、メッセージが読めないよ。CMでやってるハズキルーペが欲しくなる。以前、ホームセンターで、もどきが売られているのを見たんで、こんな時用に一つ買っておくか。
虫眼鏡で拡大したら、fsckやれば直るかも、、、なんて言ってる。
普通にfsckって叩いてもエラーで撥ねられた。fsck /dev/sda1 としたら、認可されたよ。でも、永遠に続くかと思われる、祈ってyするか、すっ飛ばすかの質問。いやになる程ね。
で、やっと解放されて、動き出した。やられていたのは、カーネルのヘッダーの所だった。 こういう場合は、再度ヘッダー部分を入れ直した方がよいのだろうか?
まあ、行ける所まで行って、だめになったら縁の切れ目とばかり Kubuntuでも入れてみるか。(密かにダメになる事を期待してるオイラーが居る。悪魔の心を持った人だな)
で、少しこの不幸続きを考察しておくかな。
一番怪しそうなのは、SSDかな。どこ製だ。ウブが立ち上がっているので、dmesgしたけど、馬鹿dmesgで、ハード寄りな情報は出てこない。
sakae@ub:~$ sudo dmesg | grep sda [ 3.476829] sd 2:0:0:0: [sda] 83886080 512-byte logical blocks: (42.9 GB/40.0 GiB) [ 3.477012] sd 2:0:0:0: [sda] Write Protect is off [ 3.477016] sd 2:0:0:0: [sda] Mode Sense: 61 00 00 00 [ 3.477226] sd 2:0:0:0: [sda] Cache data unavailable [ 3.477232] sd 2:0:0:0: [sda] Assuming drive cache: write through [ 3.479912] sda: sda1 [ 3.481106] sd 2:0:0:0: [sda] Attached SCSI disk [ 4.006302] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null) [ 4.630005] EXT4-fs (sda1): re-mounted. Opts: errors=remount-ro
BSDに慣れた人には、違和感を感じるぞ。
sakae@ub:~$ sudo parted -l Model: VMware, VMware Virtual S (scsi) Disk /dev/sda: 42.9GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 1049kB 42.9GB 42.9GB primary ext4 boot
実マシンにウブを入れていても、こうやってコマンドを叩くしかないのか? ああ、以前、FuguItaを動かした時の記録が残っていたな。
sd0 at scsibus1 targ 0 lun 0: <ATA, SAMSUNG MZ7LN256, EMT0> SCSI3 0/direct fixed naa.5002538d00000000 sd0: 244198MB, 512 bytes/sector, 500118192 sectors, thin
次に疑うのは、メモリーかな。宇宙人がいたずらに、強力な宇宙線を放射していたりして。 それで、メモリーがソフトエラーを起こした。でも、民生用のパソコンにECCなんて機能は 積んでいない。よって、エラーが見逃されてしまったとな。
spdmem0 at iic0 addr 0x50: 4GB DDR3 SDRAM PC3-12800 SO-DIMM spdmem1 at iic0 addr 0x52: 4GB DDR3 SDRAM PC3-12800 SO-DIMM
これだけじゃ、メーカー名とかは特定出来ず。
症例も沢山集まった事だし、総合診療医に久しぶりに連絡を取ってみるかな。現在、先生は岩手の山奥で、隠遁生活をしてるとか。元気してるかな?
NetBSD 7.1.2
Debian機にNetBSDを入れてたのを思い出した。vboxでは途中でエラーになるんで (OpenBSDも同様)、qemuに入れた。複数のアプリが使えると、こういう場合は有り難い。 心配していた速度も面も、同じ石を利用するせいか、余り気にならない。この点、qemuでarmをやろうとすると、気が遠くなる程、待たされる。
nb712$ df Filesystem 512-blocks Used Avail %Cap Mounted on /dev/wd0a 1050478 172782 825174 17% / /dev/wd0f 493918 124920 344304 26% /var /dev/wd0e 23825004 6159360 16474396 27% /usr /dev/wd0g 14735116 28 13998336 0% /home tmpfs 845064 8 845056 0% /tmp kernfs 2 2 0 100% /kern ptyfs 2 2 0 100% /dev/pts procfs 8 8 0 100% /proc tmpfs 130808 0 130808 0% /var/shm
インストールした時、お任せと言うか、スライスを切るのが面倒だったので、こんな風に分かれてしまった。これが正しい切り方なんだろうね。
pkgin install emacs とかすると、/varの下にpkgの素材がキャッシュされるんで、適時に クリアする事が肝要だ。
nb712$ ls /usr/src/sys/arch CVS atari evbsh3 landisk next68k sparc Makefile bebox evbsh5 luna68k ofppc sparc64 README cats ews4800mips m68k playstation2 sun2 aarch64 cesfic hp300 mac68k pmax sun3 acorn26 cobalt hpc macppc powerpc sun68k acorn32 dreamcast hpcarm mips prep usermode algor emips hpcmips mipsco rs6000 vax alpha epoc32 hpcsh mmeye sandpoint x68k amd64 evbarm hppa mvme68k sbmips x86 amiga evbarm64 i386 mvmeppc sgimips xen amigappc evbcf ia64 netwinder sh3 zaurus arc evbmips ibmnws news68k sh5 arm evbppc iyonix newsmips shark
相変わらず、石の博物館状態。世間から忘れ去られた石が陳列されてる。これ全部、最新のカーネルが動いているのだろうか? NetBSDの人に聞いてみたいぞ。
手元にも置いておきたいと思って、64Bit機にも入れてみた。そろそろ8.0が秒読みみたいで、 近くにあるサーバーからはpkgが消えていた。そこで、下記のように集積地を探して設定(Install時)したよ。
nb$ cat /usr/pkg/etc/pkgin/repositories.conf : http://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/amd64/7.1.2/All
Index of pub/pkgsrc/packages/index.html
から辿って行けば良い。
cut
前回の最後にちょろっと登場した、cut君。tasklistから必要なものを取り出すのに使った。 取り出したものを、ps風に並び変えようと、
cut -f2,1,5,6,7 -d','
とか、やっても、フィールドの並びは、-f1,2,5,6,7 のようになってしまう。こういう時は、四の五の言わずにソースに当たれ。ああ、その前に仕様書のmanが先か。 一番きちんとしてる、OpenBSDをみます。
Column and field numbering starts from 1; output is in the same order as input, not in the order selected.
対訳
列番号とフィールド番号は1から始まります。 出力は入力と同じ順序であり、 選択された順序ではありません。
オイラーみたいに、そそっかしい人向けの説明が、きちんとなされている。結局、オイラーの早とちりだった訳ね。で、参考にawkをどうぞって紹介されてたぞ。親切だなあ。
STANDARDS The cut utility is compliant with the IEEE Std 1003.1-2008 ("POSIX.1") specification.
いにしえの昔から有るコマンドと思っていたら、そうでもないのね。
HISTORY A cut command appeared in AT&T System III UNIX.
FreeBSDには、こんな記述が有ったぞ。いきなりPOSIXに登場するはずは無いものね。色々な資料に当たるのは重要。
IEEE Std 1003.1-2008 (Revision of IEEE Std 1003.1-2004)
規格書は著作物で、購入してください。と、アメリカの団体は申しております。(US$240)日本もそだね。 だったら、規格書替わりにmanとソースを読むのさ。
ob6$ cut usage: cut -b list [-n] [file ...] cut -c list [file ...] cut -f list [-s] [-d delim] [file ...]
なお、現場にmanもソースも無い場合、コマンドを思い出せるようにヒントが用意されてるよ。
あっ、うろうろしてたら、 POSIXの規格書(JIS版)なんてのに出会って、 このページをずっと下の方にスクロールしてくと、SFUなんてのが出て来る。 マイクロソフトは、今WSLを一生懸命に押しているけど、昔はSFUなんてのをやってたね。 懐かしいな。SFUみたいにWSLを投げ出すなよ。梯子を外すんじゃねーぞ。>MS。
source収集
折角なので、cutコマンドのソースを集めてきて、比べてみるかな。BSD系は、何の苦労もなく集められる。/usr/src/usr.bin/cut の中にあるからね。例えば、OpenBSDなら
sakae@ub:~/cut/ob$ ls cut.1 cut.c Makefile
こんな具合に、manの原稿、ソース、バイナリー作成自動化レシピ(Makefile)が、セットになって置いてある。ソースが複数になる場合は、ヘッダーファイルが(大体)付属してる。
問題は、Linuxだ。まあ、第二のWindowsを目指すOSとしては、ソース? 何それ、美味しいのって人が大半。目の前に美味しいソースが大量に有るのに、それを見ずして、OSS素晴らしいと言う人ばかりだからね。
cut.cが、どのモジュールに入っているか同定する所から始める。そのためには、ちょっとした下準備が必要。
sudo apt install apt-file sudo apt-file update sudo vi /etc/apt/source.list : deb-src http://us.archive.ubuntu.com/ubuntu/ bionic main restricted sudo apt update
何か所か、コメントされてるdev-srcのコメントを外す。 以上は、ソースと仲良くなる為の儀式と言うか、ソース倶楽部への登竜門。
早速、cutのソースを探してみる。
sakae@ub:/tmp$ apt-file search /usr/bin/cut abinit: /usr/bin/cut3d autocutsel: /usr/bin/cutsel coreutils: /usr/bin/cut :
coreutilsに収納されてる事が分かったので、後はゴミがちらからないように適当なdirを作って、その中で、
sudo apt source coreutils
すれば良い。coreutils-8.26なんてdirの中にsrcが有り、その中にcut.cが入っている。他にも有名な所では、ls.cなんてのも有る。このlsを題材に本を一冊書いた方がおられたな。 lsを読まずにプログラマを名乗るな!
若干リナのソース集めに苦労したけど、下記のようになった。
sakae@ub:~/cut$ wc */*.c 479 1775 11028 fb/cut.c 609 2048 16866 li/cut.c 306 1168 7500 nb/cut.c 95 468 2953 nb/x_cut.c 330 1153 7284 ob/cut.c
ざっと見、fb(FreeBSD)とli(Linux)の行数が大きいなあ。似た者同士? nb(NetBSD)は、ソースが二本立てだよ。ob(OpenBSD)が、一番すっきりしてる。
man 比べ
ソースがリナに集まってしまったものだから、文書を大事にするBSD系のmanは読めないな。 はて、どうする?
sakae@ub:~/cut$ mkdir -p man/man1 sakae@ub:~/cut$ mv fb/cut.1 man/man1/fb.1 sakae@ub:~/cut$ mv nb/cut.1 man/man1/nb.1 sakae@ub:~/cut$ mv ob/cut.1 man/man1/ob.1 sakae@ub:~/cut$ man -M /home/sakae/cut/man nb
一次的にman用の構造を作り、そこに原稿を放り込む。後は、manpathを指定して読む。
リナの場合は、manはもう古いしきたりとばかりに、余り大事にされていない模様。その代わり、バイナリーに説明が埋め込まれているな。
sakae@ub:~/cut$ cut --help Usage: cut OPTION... [FILE]... Print selected parts of lines from each FILE to standard output. : N N'th byte, character or field, counted from 1 N- from N'th byte, character or field, to end of line N-M from N'th to M'th (included) byte, character or field -M from first to M'th (included) byte, character or field GNU coreutils online help: <http://www.gnu.org/software/coreutils/> Full documentation at: <http://www.gnu.org/software/coreutils/cut> or available locally via: info '(coreutils) cut invocation'
GNU は、manよりinfoがお好みのようです。emacsのinfoを使う派が健在なんですかね。 オイラーは、infoだとsearchが面倒(と、思っているだけかも)なんで、余り使っていない。 この習性を修正せんとな。
2本立てのNetBSD
ざっくりwcした時、NetBSDは2本立てだった。行数からして、1本にしちゃっても何の問題も 無いと思うんだけど。。。ソースを見れば、何か分かるかも。
x_cut.cにその理由が述べられていた。
/* * This file is #include'd twice from cut.c, to generate both * single- and multibyte versions of the same code. * * In cut.c #define: * CUT_BYTE=0 to define b_cut (singlebyte), and * CUT_BYTE=1 to define c_cut (multibyte). * */ #if (CUT_BYTE == 1) # define CUT_FN b_cut # define CUT_CH_T int # define CUT_GETC getc # define CUT_EOF EOF # define CUT_PUTCHAR putchar #else # define CUT_FN c_cut # define CUT_CH_T wint_t # define CUT_GETC getwc # define CUT_EOF WEOF # define CUT_PUTCHAR putwchar #endif void CUT_FN(FILE *fp, const char *fname __unused) { CUT_CH_T ch; int col; char *pos; :
バイト単位でcutするのも文字単位でcutするのもやり方は同じ。ただ内部で使う関数とかが違うだけだよと。だったら、マクロ(風)にしちゃえ。なる程ね。
cut.c 内の、最後の所で、マクロ呼び出しが来ています。展開はincludeって事は、cppがやってるのね。なんか、lispみたいだな。面白いぞ、NetBSD!
/* make b_put(): */ #define CUT_BYTE 1 #include "x_cut.c" #undef CUT_BYTE /* make c_put(): */ #define CUT_BYTE 0 #include "x_cut.c" #undef CUT_BYTE
Linuxのソースは外国語
みたいに思える。その一つに、コメントの丁寧さが有ると思うぞ。emacsで閲覧してると、色が 付くんで、コメント色は飛ばせば済む事なんだけど、ついつい目がトレースしちゃうんだよな。
どのぐらい、コメント入ってる? コメントをcutして行数を数えるか。まずは、コメントを削除するプログラムを探す。(他人任せですみません)
python版をコピペ。対象ファイルは埋め込んでます。コメントの有った所は、空行になるんで、 後で、空行を削除しました。
sakae@ub:~/cut/tmp$ ./del.py | wc 610 1300 12472 sakae@ub:~/cut/tmp$ ./del.py | sed '/^$/d' | wc 449 1300 12311
全体の1/4は、コメントでした。親切なんだな。
でも、コメントは英語。そしてソース内で使われている変数名とかも、どなたかのご指導により、英語の長ったらしいものが使われてる。ソース全体が黒っぽい英文に見えるんだ。インデントが、2に設定されてるんで、余計に拍車がかかっている。
英語ネイティブな人にはいいだろうけど、母語が日本語の人には辛い。 そこに眼を付けた人が居た。
スラスラ読める Pythonふりがなプログラミングなんてのや、Javascript版が出てる。こういう風に単語が母語で理解出来ると、嬉しいぞと。
source code 類似性
BSD系のソースは、似てると思うんだけど、どのぐらい似てる? diffでいいじゃんなんてのは駄目。そこで、上の検索語で聞いてみた。
出てきたのは、学術論文の類。大学ではコピペが流行っているんで、それを検出するために、先生方は、日夜研究に励んでおられるんだな。コードが公開されないのは、学生に裏をかかれないようにする為に違いない。
最近のトレンドは、人口知能で賢く検出しましょって事らしい。何とかしたいと言う、切実な現実的が有るんでしょうな。
で、下記の物が使えそう。
リファクタリングのお供に。ソースコードの類似点を検索する「Unique」
MariaDB と MySQL のソースコードの類似度を調べる
たまには、手を動かしてみるかって事で、Windows用に作られているものをlinux用に移植してみる事にする。
#!/bin/sh # Usage: copipeP.sh ref-file cmp-file a=$1 b=$2 saa=`cat $a $a | wc -c` zaa=`cat $a $a | gzip -c | wc -c` faa=`echo "$zaa * 10000 / $saa" | bc` sab=`cat $a $b | wc -c` zab=`cat $a $b | gzip -c | wc -c` fab=`echo "$zab * 10000 / $sab" | bc` echo "Same file : 100, Differ file : > 100" echo "$fab * 100 / $faa" | bc
手を動かす程の事は無かった。コードを書いて、C-c C-x で検証しながらね。
sakae@ub:~/cut/tmp$ ./copipeP.sh li.c li.c Same file : 100, Differ file : > 100 100 sakae@ub:~/cut/tmp$ ./copipeP.sh li.c fb.c Same file : 100, Differ file : > 100 197 sakae@ub:~/cut/tmp$ ./copipeP.sh ob.c fb.c Same file : 100, Differ file : > 100 132
同一ファイルは、勿論100。リナとBSDは、似ていない。BSDでも、同族系なら似てると判定。 妥当な結果ですな。
もう少し、実例っぽいやつをやる。Javascriptを手元でガシガシ書いた。Webに上げる時、難読化と称して、コメントを外したりする事がある。そういうのと元ファイルの一致度は、どうなん?
sakae@ub:~/cut/tmp$ ./del.py >noc.c sakae@ub:~/cut/tmp$ wc li.c noc.c 609 2048 16866 li.c 610 1300 12472 noc.c sakae@ub:~/cut/tmp$ ./copipeP.sh li.c noc.c Same file : 100, Differ file : > 100 116 sakae@ub:~/cut/tmp$ ./copipeP.sh noc.c li.c Same file : 100, Differ file : > 100 130
コメントを外したnoc.cを作る。元ファイルを基準にすると、類似度は116で、非常に似ている判断(で、いいかな)。
逆のパターンもやった。想定は、コメントも何も無いファイルを落としてきて、それを解析、コメントを付けた。これで、ソースレベルでは、オリジナリティが出た。類似度は130で、元と似てない度が高まった。
そうか、色々なソースを解析して、これにコメントを追加していくと、誰からも文句を付けられないものが出来上がる。本を上に出て来た人のように出版出来るとな。
その元祖は、 2238クラブ に出てくるLions本。 それを近代化させた、 はじめてのOSコードリーディング なんかに、なるわけだ。
cutの肝
折角なので、cutのコードを見ておく。素直なFreeBSDでgdbを使って、要所を押さえる。
cut -b 10-20,24-28 cut.c
を実行。文字を拾い出すためのフラグをmainの中でget_listを呼び出して設定してる。 下記は、その設定が終了した時の図。
(gdb) x/30xb positions 0x800e17000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x800e17008: 0x00 0x00 0x01 0x01 0x01 0x01 0x01 0x01 0x800e17010: 0x01 0x01 0x01 0x01 0x01 0x00 0x00 0x00 0x800e17018: 0x01 0x01 0x01 0x01 0x01 0x00
文字のポジションで拾うべき所が1に設定されている。拾わなくても良い所は、zeroになってる。needpos関数によって、この配列を拡張かつ初期値をzeroに設定。そのうち拾うべき所に1を書いて、目印を作っている。
それじゃ、10- のような無限大とも解釈出来る要求をどう解決する? そんな配列定義出来ないぞ。
そういう不都合を吸収する為に、大域変数 autostart, autostop, maxvalが使われています。これらの変数の設定条件によって、無限を上手く吸収してます。詳しくはsourceで。
OpenBSDでは、このpositions配列サイズが決め打ち。NetBSDでは、
static size_t autostart, autostop, maxval; static char *positions = NULL; static size_t numpositions = 0; #define ALLOC_CHUNK _POSIX2_LINE_MAX /* malloc granularity */ static void get_list(char *list) { : if (positions == NULL) { numpositions = ALLOC_CHUNK; positions = ecalloc(numpositions, sizeof(*positions)); } :
こんな風に確保してる。それにしても、_POSIX2_LINE_MAX って、何処で定義されてるのだろう? 強引にサイズを調べてみる。
ob6$ cc -E cut.c | grep positions char positions[2048 + 1]; :
cppによるマクロ展開(かな?)。Lisp屋さんの大好きな事だ。1行の長さが2048って、まあ実用的なサイズか。でも、デザイナーベビーを作る時に使う、遺伝子塩基の切り貼りだと、もっと長い場所から切り出す事が有るだろうね。そんな時は、OpenBSDのcutを諦めて、FreeBSDなりのそれを使ってください。
上のPOSIX2_LINE_MAXを大域的に探そうと、find /usr/src なんてやったんだ。そしたら、所々でエラーが発生。findがエラーを返してきた時は、その先を辿ってくれないみたい。それで、場所を特定出来なかったのだな。探すなら、あたりを付けてincludeの下だけを対象にしろ。知らなかったのは、オイラーだけ?
なお、 最初、linuxのソースの塊からcut.cを抜き出して、gdbにかけられるようにコンパイルしようと 思ったんだけど、殊のほか面倒そうだったので、BSDに逃げた。BSDはそれぞれのコマンドが独立してて、こういう時は非常に便利。やっぱり、リナでソースを見たり解析するのは、時間の無駄、ストレス無限大になると思うぞ。オイラーもすっかり、BSD小僧になっちまったな。
etc
これは、WSLの記事と言うか、Windows屋さんをLinuxへ誘う記事。wslでもvirtualboxでも、Linuxが動けばいいよね。そして、Windowsの貧弱なターミナルを便利なものに置き換えようという戦略。
続いて、Xを動かすとかやるのかしら?