残念ながら私は全くOracleというDBMSが使えません。どれくらい使えないかというと、
SQL> SHOW DATABASES; SP2-0158: unknown SHOW option "DATABASES"
( ゚д゚)ノ せんせー、このDBMSダメなやつです!
というくらい使えません。PostgreSQLだったらまだコマンドラインクライアントをゴニョって`SHOW DATABASES`で一覧を出すくらいのことは出来たんですが、sqlplusだとそういう訳にも行きませんね、このクローズドソース野郎!!1
という訳で、sqlplus使い御用達(と聞いている) rlwrap の話をしようと思います。わたしは groonga (コマンドラインクライアントの方)でrlwrapをよく使いますが、初めてオプションを調べてみたので記録しておきます。
有名な話だったらごめんなさい。
まずは単に起動。
$ rlwrap sqlplus SQL*Plus: Release 11.2.0.4.0 Production on Mon Dec 7 18:52:56 2015 Copyright (c) 1982, 2013, Oracle. All rights reserved. Enter user-name: supersuper Enter password: **********
とまあこの通りパスワード部分はreadlineを通らず、"*"でマークされました。
Enter叩いた瞬間に"*"も消えました。sqlplus、こんな動作なのか。
そしてそこで有名なやつとして-aオプションを足してみると
$ rlwrap -a sqlplus SQL*Plus: Release 11.2.0.4.0 Production on Mon Dec 7 18:59:45 2015 Copyright (c) 1982, 2013, Oracle. All rights reserved. Enter user-name: supersuper Enter password: top_s3cret
如何にもありそうな感じで、剥き出しでパスワードが表示される。本来、パスワードっぽいものを遠慮してreadlineに流さずにやってるのを、全部readlineに通してそのあとNL契機でsqlplusに渡してるんですね、たぶん。"*"の時と同じくエンター叩いた瞬間に消えますが、SQLのプロンプトで↑キーを押すと
SQL> top_s3cret
履歴に出た━━━━(゚∀゚)━━━━!!
readlineに渡るとhistory_fileにも書くからか。そうか、確かにそうだけど面白い。
$ rlwrap -a"Enter password:" sqlplus SQL*Plus: Release 11.2.0.4.0 Production on Mon Dec 7 19:02:19 2015 Copyright (c) 1982, 2013, Oracle. All rights reserved. Enter user-name: supersuper Enter password: **********
-aオプションの直後(スペース文字を入れると、「スペース入れるな!」って怒られた)に指定した文字列が来た時は、パスワードだと見做してreadlineを通さなくなる、様子。
ちなみに"Enter password:"の状態で-aオプション *無し* の時でも *↑↓キーによる履歴呼び出しが可能* なので、一度パスワードが記録されると何となく雰囲気でログインできるかも知れない。
$ rlwrap -p"YELLOW" sqlplus SQL*Plus: Release 11.2.0.4.0 Production on Mon Dec 7 19:15:38 2015 Copyright (c) 1982, 2013, Oracle. All rights reserved. Enter user-name: supersuper Enter password:
う、テキストべた張りだと感動が伝わらないと思いますが、プロンプトが全て黄色太文字になってます。
"yellow"だと太文字ではない様子。"RED"だと赤太文字、"red"だと赤細文字でした。へーすごい。MySQLでいうところの--pagerにカラーコード仕込む感じですね。でもこっちの方が英語で指定できていいなぁ。ってかmysqlコマンドラインクライアントもrlwrap経由で起動させてやれば 日々の覚書: MySQL 5.6以降のmysqlコマンドラインクライアントでプロンプトに色を付けるcmakeオプション なんてのも必要なくなりそう。うむ。
$ rlwrap -z"pipeto" sqlplus .. SQL> SELECT * FROM ..; | less -S -r
そして極め付け。SQLの結果をそのまま別のプロセスにパイプで渡せるpipetoフィルター。mysqlにはpagerコマンドがあるので気楽にlessに食わせられるけれど、sqlplusにはお手軽なのがないらしい。
`-z"pipeto"`オプションを付けると、出力をパイプに向けられる。
( *出力を* 向けるので、パイプの手前までで出力が開始されてないとダメ。つまりSQLなら *セミコロンまで打ち込んでからパイプを付ける* )
ところでこれ、MySQLは文字列結合に"||"演算子を使わないから良いとして、Oracleはよく使いそう(偏見)なので、上手くやってくれ…
SQL> SELECT 'a' || 'b'; | wc sh: -c: line 0: 期待してない token `|' のあたりにシンタックスエラー sh: -c: line 0: `| 'b'; | wc' 2
る訳がなかった。そりゃ別にsqlplus用のユーティリティーってわけじゃあるまいし。
幸いにしてフィルターの類はPerlで書かれているらしいので、ちょっと探してみる。
$ rpm -ql rlwrap /usr/bin/rlwrap /usr/share/doc/rlwrap-0.41 /usr/share/doc/rlwrap-0.41/AUTHORS /usr/share/doc/rlwrap-0.41/COPYING /usr/share/doc/rlwrap-0.41/NEWS /usr/share/doc/rlwrap-0.41/README /usr/share/man/man1/rlwrap.1.gz /usr/share/man/man3/RlwrapFilter.3pm.gz /usr/share/rlwrap /usr/share/rlwrap/completions /usr/share/rlwrap/completions/coqtop /usr/share/rlwrap/completions/testclient /usr/share/rlwrap/filters /usr/share/rlwrap/filters/README /usr/share/rlwrap/filters/RlwrapFilter.3pm /usr/share/rlwrap/filters/RlwrapFilter.pm /usr/share/rlwrap/filters/censor_passwords /usr/share/rlwrap/filters/count_in_prompt /usr/share/rlwrap/filters/ftp_filter /usr/share/rlwrap/filters/history_format /usr/share/rlwrap/filters/listing /usr/share/rlwrap/filters/logger /usr/share/rlwrap/filters/null /usr/share/rlwrap/filters/paint_prompt /usr/share/rlwrap/filters/pipeline /usr/share/rlwrap/filters/pipeto /usr/share/rlwrap/filters/scrub_prompt /usr/share/rlwrap/filters/simple_macro /usr/share/rlwrap/filters/template /usr/share/rlwrap/filters/unbackspace $ vim /usr/share/rlwrap/filters/pipeto .. 50 sub input { 51 my $input; 52 $raw_input = $_; 53 ($input, undef, $pipeline) = /([^|]*)(\|(.*))?/; 54 return $input; 55 } ..
ここで切り分けているぽい。最初のパイプの手前までが元のコマンド、パイプの後ろがフィルターになってる。
そこでこんなパッチにしてみました。
*** /usr/share/rlwrap/filters/pipeto.orig 2010-01-03 21:42:16.000000000 +0900 --- /usr/share/rlwrap/filters/pipeto 2015-12-08 10:58:54.817411488 +0900 *************** *** 53 **** ! ($input, undef, $pipeline) = /([^|]*)(\|(.*))?/; --- 53,54 ---- ! ($input, $pipeline) = /(.+)?\s+\|\s+(.*)?/; ! $input= $_ unless $input;
" | "(空白、パイプ、空白。空白は1つ以上の任意の個数でOK)をパイプと認識させるように変更。
SQL> SELECT 'a' || 'b' FROM dual /* パイプを通る */; | less 'A -- ab SQL> SELECT 'a' || 'b' FROM dual /* パイプを通らない */; |less 2
パイプを通らない場合、"|less"までをsqlplusが解釈しようとするのでちゃんと出力されませんね(これは-z"pipeto"を取ってもそんな動きだった)
ざっとマニュアルを読んで面白そうだったものの紹介でした!
(個人的にはパスワードプロンプトで↑↓使えたのが面白かった)
0 件のコメント :
コメントを投稿