How to create a self made command (on Mac) シェルコマンド作成
自分でシェルコマンド作ってみたい欲が高まり過ぎたので,作成しちゃったのをlog.
rands
作成したコマンドは rands というもので,ランダムな文字列を出力するというもの.最近,講義でランダムな文字列を扱う機会が多かったのでいっそ作ったるということで作成.楽しかった.
github.com
デフォルトだと,アルファベット・記号・数字がごっちゃになった8文字を出力.オプション与えると,文字列長設定したり記号除外したりスペースを含められたりという感じのもの.
ソースコード
ちょっとソースコードに関して解説.
getopt関数
getopt関数はシェルコマンドで引数を処理してる標準関数.ハイフン後に続く文字を解釈して,いろいろ返してくれる.ググったら色々ドキュメントが出てくる.
・Man page of GETOPT
・コマンドライン引数の取得とgetopt
・getoptによるオプション解析
がしかし...最初は
$ rands 10 -an $ rands -A 10
みたいな感じで,文字列長はハイフンなしで適当に指定したかったのだが,ハイフンなしの引数の処理がイマイチわからなかったので,そこは今後の課題に.特に,ハイフン無し引数がハイフンより先に来た時は,他の引数も処理してくれなかったのが謎だった.
rand()とtimeval.tv_usec
最初は
srand((unsigned) time(NULL)); rand();
だけで実装しようとしたのだが,連続実行すると文字列に変化がないので,マイクロ秒まで使ってsrandを指定するようにした.
8ttyan.hatenablog.com
struct timeval tv; gettimeofday(&tv, NULL); srand((unsigned) tv.tv_usec);
がしかし...これでも複数回実行すると,文字列に規則性があるのが見えてくる.実装で,ランダム値によって文字と記号と数字のどれを出力するかを決めてるのが問題になってるっぽい.
switch((random()%5+1){ case 1: ... }
ここも,よりランダムっぽくなるように,timeval.tv_usecを使って以下のように工夫した
switch((random()+myTime.tv_usec)%5+1){ case 1: ... }
これで,かなりランダムに出力されるようになった気がした.
コマンド化
qiita.com
Cのソースコードをそのままコンパイルしただけでは,実行する際に
$ ./rands -l 10 -nA
みたいに実行ファイルの場所を指定しなくてはいけないので,他のシェルコマンドのように実行できるようにする.それが install.sh に描かれている.やっていることは,
これだけで,自分で作成したプログラムをシェルコマンドみたいに使うことができる!
まとめ
getoptやrandのいい練習にもなって,自作コマンドを作れて楽しかった!まだまだ学ぶことは多いけど,今後もガンガン自作コマンド作っていきたい.あとは,シェルスクリプトもコマンド化できるみたいなので,その辺もガンガン作っていきたい.