Groovy Shell Scripting 2015
-
Upload
- -
Category
Technology
-
view
369 -
download
4
Transcript of Groovy Shell Scripting 2015
Groovy Shell Scripting 2015JGGUG G*Workshop 2015/06/26 上原潤二(NTTソフトウェア)
わたくしは上原潤二(@uehaj) NTTソフトウェア(株)Grails推進室 JGGUG運営委員
書いたり プログラミングGROOVY(技術評論社) Grails徹底入門(翔泳社) ブログ「Grな日々」
Groovyスクリプト使ってますか?Groovyスクリプトとは クラス定義に囲まれていない、トップレベルの文や関数定義から構成 binding変数が使える コンパイルしない
スクリプトは日々作業に便利編集してすぐ再実行できる
コンパイルやIDEやGradleとかは不要
おおげさなインストールも不要(置くだけ)
でも…
いくつか問題がある。プロセスの扱い
クラスパス問題
(問題1) プロセスの扱い
プロセス起動の諸問題
"ls -l".execute() 出力は?
println("ls -l".execute().text) 標準エラーはどこへ?
"ssh host.example.com ls".execute()
パスワードを聞いてきたら何がおきる?
ProcessBuilder#inheritIO()
本日のネタ:これをGroovyらしい形で有効活用しようではないか
String.metaClass.execString.metaClass.exec0 = { def st = new StringTokenizer(delegate) new ProcessBuilder(st.collect()).inheritIO().start() }
"login".exec0().waitFor() println "done"
waitForはProcessのメソッド
パイプString.metaClass.or = { String rhs -‐> delegate.execute() | rhs.execute() } Process.metaClass.or = { String rhs -‐> delegate | rhs.execute() } String.metaClass.or = { Process rhs -‐> delegate.execute() | rhs }
"echo 123abc" | "tr 'a-‐z' 'A-‐Z'" | "grep B".exec(input:Redirect.PIPE)
色付きGrepが機能(isatty)
https://github.com/uehaj/groovy-shell-scripting-examples
リダイレクト@groovy.transform.BaseScript(cmd.Base1) import java.lang.String
"sed -‐e s/[a-‐z]/A/g".exec(input:"input.txt", output:"output.txt")
println new File("input.txt").text println new File("output.txt").text
https://github.com/uehaj/groovy-shell-scripting-examples
メソッド追加はいつやるの?staticイニシャライザ
不安
拡張メソッド?
Jarに梱包する必要がありスクリプト用としては面倒
@BaseScriptで簡単確実Since: Groovy 2.2.0
package cmd
import java.util.StringTokenizer import static java.lang.ProcessBuilder.Redirect
abstract class Base0 extends Script { abstract Object runScript()
Object run(){ String.metaClass.exec = { def st = new StringTokenizer(delegate) new ProcessBuilder(st.collect()).inheritIO().start() } String.metaClass.or = { String rhs -‐>
delegate.execute() | rhs.execute() } Process.metaClass.or = { String rhs -‐> delegate | rhs.execute() } String.metaClass.or = { Process rhs -‐> delegate.execute() | rhs } runScript() } }
@groovy.transform.BaseScript(cmd.Base0) import java.lang.String
"login".exec().waitFor() println "done"
@BaseScriptの有用性DSLを作るための手軽な仕掛け置き場
methodMissing, getProperty…
Groovyスクリプトでは特定の名前の変数を定義(クロージャ、マップ、…)
それに対してBase側で任意の処理
(問題2) クラスパス問題
スクリプトのクラスパス問題(1 of 2)スクリプトを実行可能プログラムのように起動 そのとき、以下を読めるようにクラスパスを指定したい @BaseSciriptの対象 スクリプトから利用するクラス
問題: shebangは$0を解釈しない
スクリプトのクラスパス問題(2 of 2)スクリプトの場所($0)相対で読みこんで欲しい スクリプトごとにCLASSPATH環境変数に追加したくない😔
すべてを~/.groovy/libにぶちこむのはもっと嫌😖
Perl, Ruby, Pythonなどではあたりまえの話 Groovyスクリプトを呼び出すShell Script/.batを書く
あきらかな負け😖
Linux,MacOS以下のようにすると勝つる😃
#!/bin/bash //usr/bin/env groovy -‐cp "`dirname $0`" "$0" $@; exit $?
@groovy.transform.BaseScript(cmd.Base1) …
├── thisscript.groovy └── cmd/ └── Base1.groovy
WindowsスクリプトはPATHの通ったところに置いた上で「管理者として実行」したコマンドプロンプトで以下を実行
ただし、
PATH配下をすべて見てしまう😟
「ダブルクリックしてスクリプト起動」に対応しない
assoc .groovy=groovyscript ftype groovyscript=C:\groovy-‐2.4.1\bin\groovy.bat -‐cp "%PATH%” "%1" %*
まとめ日々作業はGroovyで片付けよう!!
おまけ
docopt.java便利
参考リンクなど@BaseScriptアノテーションはscriptをインクルードするのに使えますhttp://uehaj.hatenablog.com/entry/2014/04/25/220853
https://github.com/docopt/docopt.java
サンプルコードhttps://github.com/uehaj/groovy-shell-scripting-examples