いつも使っているtcshやBourneシェルとはかなり違った文化な感じで、とりあえず入れて少し触ってみた、という程度の内容です。
Perl Shellのインストール
cpanmでもインストールできるのですが、最初にそれで入れたpshは動作がおかしかったので、githubからソースを持ってきて、必要なモジュールを入れてからmake installしました。インストールしたのはうちのMacで、実行に使用したPerlは5.14.2です。
% cd /usr/local/src⏎
% git clone https://github.com/gnp/psh.git⏎
Cloning into psh...
remote: Counting objects: 5457, done.
remote: Compressing objects: 100% (2064/2064), done.
remote: Total 5457 (delta 2878), reused 5410 (delta 2831)
Receiving objects: 100% (5457/5457), 974.67 KiB | 373 KiB/s, done.
Resolving deltas: 100% (2878/2878), done.
% cd ./psh⏎
% sudo cpanm BSD::Resource Term::ReadLine::Gnu⏎
...
% perl Makefile.PL && make && sudo make install⏎
...
Installing /usr/local/bin/psh
Appending installation info to /usr/local/lib/perl5/5.14.2/darwin-2level/perllocal.pod
/usr/local/bin/perl postinstall.pl /usr/local /usr/local
Installing share files to /usr/local/share/psh
% rehash && which psh⏎
/usr/local/bin/psh
PerlのShellと言えばアコヤガイ |
うまいことビルドとインストールが終わったらPerl Shellは /usr/local/bin/psh (/usr/bin/perlを使ったら /usr/bin/psh になる、たぶん)が利用できるようになっているはずです。
Perl Shellを起動
一般的なShellを起動するのと同じで、pshを実行するとPerl Shellが起動します。コマンドなのでマニュアルはman pshで読みます。あるいはWebで。% /usr/local/bin/psh⏎
psh%
psh% man psh⏎
サンプルコマンドを試す
manに書いているような簡単なサンプルを試しました。sedの代わりとして
psh% ls -laF | s/May/五月/g⏎
total 224
drwxr-xr-x 33 user admin 1122 五月 22 20:16 ./
drwxrwxr-x 48 root admin 1632 五月 22 20:14 ../
drwxr-xr-x 13 user admin 442 五月 22 20:14 .git/
-rw-r--r-- 1 user admin 70 五月 22 20:14 .gitignore
...
行番号を付ける(quick filter)
psh% ls -F1 | { printf "%02d %s", ++$x, $_ }q⏎
01 CHANGES.pod
02 COPYRIGHT
03 HACKING.pod
...
末尾のqはquick filterとして動作するようで、{ }内のコード実行結果だけ表示されるようです。逆にqを付けないと、ls -1Fの実行結果と | {...}の処理結果がそれぞれ表示されます。Perlっぽいもの
tcshとbashに於て環境変数やシェル変数の宣言は、=を付けるか付けないかの違いがあってたまに間違えますが、Perl ShellではPerlの変数宣言と同じように記述して変数が作れます。Scalar, Array, Hash, それとリファレンスも使えます。環境変数も%ENVへアクセスすれば読み書きが可能です。
他にもPerlの関数をそのままコマンドラインから呼び出したりできるので、UNIXコマンドを意識しなければ、そのままPerlのインタラクティブシェルのような感じで使えます。
psh% $x = 9⏎
psh% print $x.qq(\n)⏎
9
psh% $y = [ 1..10 ];⏎
psh% print $_.qq(\n) for @$y;⏎
1
2
3
4
...
10
psh% map { $_ *= 10 } @$y;⏎
psh% print $_.qq(\n) for @$y;⏎
10
20
30
...
psh% print $ENV{SHELL}.qq(\n)⏎
/usr/local/bin/psh
ちょっと応用してみた感じの試行
RSSが一定以上のプロセスを絞り込む(grep filter)
psh% ps axu | head -2⏎
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
hoge 260 5.2 1.7 2604588 71088 ?? S 7:15PM 1:25.32 /Applications/Utilities/Terminal.app/Contents/MacOS/Terminal -psn_0_90134
psh% ps aux | { $_[5] > 1024 * 100 }g⏎
...
psを実行した結果、うまいことスペース(かタブ?)でsplitされたものが@_に入るので、RSSはPerlの配列では5番目(0から始まる)です。
なので$_[5]が100MB(1024KB * 100)以上のプロセスだけを絞り込めます。この動作は末尾のg(grep filter)によるものだそうです。
同じようにCPU使用率が50%以上のものを絞り込んだりする数値計算によるフィルタが考えられます。
このあたりは従来の伝統的なUNIXコマンドを駆使するよりも簡単に結果を得られる気が(たぶんawkでも同じ事が出来ると思います、たぶん...)します。
Time::Pieceモジュールを使って6時間以内のaccess_logを取り出す
同じくgrep filterですが、モジュールも使えます。いつも書くPerlと同じくuseで呼ぶとShellを終了するまでずっと使える状態になります。requireでも同様に読み込めますが、Perl Shellに於けるuseとrequireの動作の違いは知りません。
下記はTime::Piece->strptimeでaccess_logの日付・時刻をマシンタイムに変換して現在時刻と比較して6時間以内のログだけを取り出している例です。
psh% cd /usr/local/httpd/logs⏎
psh% use Time::Piece;⏎
psh% cat access_log | { $x = localtime Time::Piece->strptime( $_[3], "[%d/%b/%Y:%T" ); $x > time - 21600 }g⏎
...
ほかのShellと違うところ
標準エラーを捨てる時の 2> /dev/null の書き方が違います。manにはサポートしてないって書いてあり、かわりに下記のように記述するようです。% /usr/local/bin/psh⏎
psh%
psh% /bin/ls /tmp/hoge/fuga/piyo >[2] /dev/null⏎
[1] Error 11778 ls -1 /tmp/hoge/fuga/piyo
ファイルディスクリプタ番号は同じ2ですが、書き方が少し違います。
他には、
- pushd/popdがない(eval errorって言われる)
- ( cd /tmp && touch ./test.txt )を実行するとeval error (Illegal division by zero...ってエラー
挙動不審なところ :-(
/usr/local/bin/psh -wで起動すると、
- コマンド実行で``Use of uninitialized value $num in numeric eq (==)...''とか出る
- どのコマンドを実行しても↑がでる(´ヘ`;)
-wを付けなくても、たまに起きるのが
- cd /usr/local/src等実在するディレクトリへ移動できない事がある(No such ...)
- /sbin/ifconfigを実行すると``Having no space between pattern and following...''と出る事がある
などなど、やや挙動不審なところがありました。pshを起動し直すと回復します、ソース見て原因特定とかやってません。
まとめ
とりあえず入れて使ってみた、という段階の内容です。僕はサーバエンジニアなので、bashすらない古代のシステムに入る事もあり、おそらく標準では入っていないであろう近代的なShellにどっぷり浸かる事はないと思います。
Perl Shellの利点としては、sed, awkなどのUNIXコマンドに精通していないけどPerlなら分かるって場合に、在る程度のオペレーションが出来るのかなぁって所かと思います。
あるいはShellとしてではなく、Perlのインタラクティブシェルとして使う、という姿勢の方がPerl Shellって便利と思えるかもしれません。
あるいはShellとしてではなく、Perlのインタラクティブシェルとして使う、という姿勢の方がPerl Shellって便利と思えるかもしれません。
0 件のコメント:
コメントを投稿