groovy on the shell

43
GROOVY ON THE SHELL SHELLSCRIPTING WITH GROOVY Alexander Klein / http://codecentric.de [email protected] 0

Upload: saschaklein

Post on 15-Jul-2015

1.310 views

Category:

Software


6 download

TRANSCRIPT

GROOVY ONTHE SHELL

SHELLSCRIPTING WITH GROOVYAlexander Klein / http://codecentric.de [email protected]

0

WHY ?

GROOVY IS

COOL

BECAUSE I

CAN

TO DO COMPLEX STUFF

TESTING YOUR SCRIPTS

IF YOU KNOW GROOVY BETTER THAN BASH

ALEXANDER (SASCHA) KLEIN 

Principal Consultantcodecentric AG

Stuttgart 

Groovy, JavaFX, UI / UX 

Griffon committer 

[email protected]@saschaklein

http://gplus.to/karfunkel

EXECUTINGGROOVYSCRIPTS

$ groovy Test.groovy

SHE-BANG-COMMENT (#!)#!/usr/local/bin/groovy

USING THE DEFAULTENVIRONMENT

#!/usr/bin/env groovy

DEFINING THE CLASSPATH#!/usr/bin/env groovy -cp myjar.jar

USING SYSTEM VARIABLES#!/usr/bin/env groovy -cp ${HOME}/bin

DEFINING SYSTEM VARIABLES#!/usr/bin/env VAR1=value1 VAR2=value2 groovy

BUTDOES NOT WORK ON LINUX

Alternative script for /usr/bin/envWithout defining system variables

#!/bin/bashARGS=( $1 ) # separate $1 into multiple space-delimited arguments.shift # consume $1PROG=`which ${ARGS[0]}` # find path for executableunset ARGS[0] # discard executable nameARGS+=( "$@" ) # remainder of arguments preserved "as-is".# iterate array and expand variablesdeclare -a PARAMSfor i in "${ARGS[@]}" do PARAMS=("${PARAMS[@]}" "`eval "echo $i"`") doneexec $PROG "${PARAMS[@]}" # execute the command

GROOVYSERV

FASTER STARTUPJVM process running in the background

Scriptstart ~10-20 times faster

INSTALLATIONWINDOWS

GroovyServ is part of the Groovy Windows-Installer

LINUXgvm install groovyserv

MAC OS Xbrew install groovyserv

BINARY PACKAGE$ cd /tmp$ unzip groovyserv-1.0.0-bin.zip$ groovyserv-1.0.0-bin/bin/setup.sh

export PATH=/tmp/groovyserv-1.0.0/bin:$PATH

USAGEgroovyclient MyScript.groovy

#!/usr/bin/env groovyclient

WRITINGSCRIPTS

RESTRICTIONSClassname == Filename

to be found from other script

EXECUTING SHELL COMMANDS

"mkdir foo".execute()

["mkdir", "my directory"].execute()

WORKINGDIR &ENVIRONMENT

"ls".execute([], new File("/tmp"))

"env".execute(["VAR1=Test", "VAR2=Something"], new File("."))

"env".execute([*:System.env, VAR1: 'Test'].collect{ k,v -> "$k=$v" }, new File("."))

RESULT ACCESSprintln "ls".execute().text

println "cmd /c dir".execute().text

"ls".execute().inputStream.eachLine { println it }"ls".execute().in.eachLine { println it }

"myCommand".execute().err.eachLine { println it }

def proc = new ProcessBuilder("myCommand").redirectErrorStream(true).start()proc.in.eachLine { println it }

PROCESS CONTROLProcess process = "mkdir foo".execute()process.waitFor()

int exitValue = process.exitValue()if(!exitValue) { //do your error-handling}

if(!"mkdir foo".execute().waitFor()) { //do your error-handling}

"grep pattern".execute().waitForOrKill(1000)

def process = "myLongRunningCommand".execute()...process.destroy()

PROCESS OUTPUTProcess process = "myCommand".execute()def out = new StringBuffer()def err = new StringBuffer()process.waitForProcessOutput( out, err )if( out.size() > 0 ) println outif( err.size() > 0 ) println err

def p = "rm -f foo.tmp".execute([], tmpDir)p.consumeProcessOutput() // Prevent blocking by small bufferp.waitFor()

PIPING"less temp.sh".execute().pipeTo("grep Detected".execute()).text

def proc1 = "less temp.sh".execute()def proc2 = "grep Detected".execute()proc1 | proc2println proc2.text

WILDCARDS"ls *.java".execute() // won't work

"sh -c ls *.java".execute() // Shell resolves the wildcard

SHELL HELPER Iclass Shell { final Map env = System.env File dir = new File('.') boolean redirectErrorStream = false long timeout = 5000

Shell env(Map env) { this.env.putAll(env); return this }

Shell dir(File dir) { this.dir = dir; return this }

Shell dir(String dir) { this.dir = new File(dir); return this }

Shell redirectErrorStream(boolean redirectErrorStream = true) { this.redirectErrorStream = redirectErrorStream; return this }

Shell timeout(int timeout = 5000) { this.timeout = timeout; return this }

SHELL HELPER II Process execute(String command) { new ProcessBuilder(['sh', '-c', command]) .directory(dir) .redirectErrorStream(redirectErrorStream) .environment(env.collect{k,v -> "$k=$v"} as String[]) .start() }

int call(String command, boolean consumeOutput = true) { Process proc = execute(command) if(consumeOutput) proc.consumeProcessOutput() if(timeout) proc.waitForOrKill(timeout) else proc.waitFor() return proc.exitValue() }

def eachLine(String command, Closure action) { execute(command).in.eachLine(action) }}

SHELL HELPER IIIdef shell = new Shell()shell.call("mkdir /tmp/groovy")shell.call("echo 123 >> /tmp/groovy/test")shell.dir("/tmp/groovy").call("echo \$HOME >> test2")shell.eachLine("ls ."){ println "- $it -"}shell.eachLine("cat test2"){ println "- $it -"}

HELPFULL STUFFACCESSING SYSTEM-VARIABLES

println System.env.PWD

ACCESSING SYSTEM-PROPERTIESprintln System.properties.'user.dir'

GET YOUR PIDimport java.lang.management.*println ManagementFactory.runtimeMXBean.name.split('@').first().toInteger()

CLIBUILDER

PARSING COMMANDLINEARGUMENTS

DSL ontop of Apache Commons CLI !#/usr/bin/env groovy

def cli = new CliBuilder(usage: 'MyScript') cli.with { v(longOpt: 'version', 'show version information') }

def opt = cli.parse(args) if (!opt) System.exit(2)

if (opt.v) { println "Version: 1.0.0" }

A SAMPLEusage: MyScript [options] [args] -?,--help usage information --config <arg> A script for tweaking the configuration -D <property=value> use value for given property -s,--source <path> Aliases for '-source' -source <path> Specify where to find the files -v,--version version information

THE CODE I#!/usr/bin/env groovy

def cli = new CliBuilder(usage: 'MyScript [options] [args]')cli.with { source (args:1, argName: 'path', optionalArg: false, 'Specify where to find the files') _ (longOpt: 'config', args:1, argName: 'arg', optionalArg: false, 'A script for tweaking the configuration') s (longOpt: 'source', args:1, argName:'path', optionalArg: false, "Aliases for '-source'") '?' (longOpt: 'help', 'usage information') v (longOpt: 'version', 'version information') D (args: 2, valueSeparator: '=', argName: 'property=value', 'use value for given property')}

THE CODE IIdef opt = cli.parse(args)if (!opt) // usage already displayed by cli.parse() System.exit(2)

if(opt.'?') cli.usage()else if (opt.v) println "Version: 1.0.0"else { if (opt.config) println "Configuration: $opt.config" if(opt.D) { println "Custom properties:" println opt.Ds.collate(2).collect{ it.join('=') }.join('\n') } def home = System.properties.'user.dir' if (opt.s || opt.source) home = opt.s ?: opt.source println "Working on files:" opt.arguments().each println "$home/$it"}

DEPENDENCYMANAGEMENT

GRAPEGROOVY ADAPTABLE PACKAGING ENGINE

@Grab(group='org.springframework', module='spring-orm', version='3.2.5.RELEASE')import org.springframework.jdbc.core.JdbcTemplate

@Grab('org.springframework:spring-orm:3.2.5.RELEASE')import org.springframework.jdbc.core.JdbcTemplate

Cachedirectory ~/.groovy/grape

@GRAB ANNOTATION IAnnotatable everywhere

often seen at import statementsgroup (String)

Maven groupId or Ivy organizationmodule (String)

Maven artifactId or Ivy artifactversion (String)

literal'1.1-RC3'

Ivy range'[1.0, 2,0]' -> 1.0 or 2.0'[2.1,)' -> 2.1 or greater

classifier (String)'jdk15'optional

MULTIPLE DEPENDENCIES@Grapes([ @Grab(group='commons-primitives', module='commons-primitives', version='1.0'), @Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7') ])class Example { ...}

REPOSITORIESConfiguration in ~/.groovy/grapeConfig.xml

Grape cache -> ~/.groovy/grapesMaven Local -> ~/.m2/repositoryJCenter (includes Maven Central)

Codehaus.org

IBiblio

Java.net

http://jcenter.bintray.com

http://repository.codehaus.org

http://www.ibiblio.org

http://download.java.net/maven/2@GrabResolver(name='restlet', root='http://maven.restlet.org/')@Grab(group='org.restlet', module='org.restlet', version='1.1.6')

EXCLUDE TRANSITIVE DEPENDENCIES@Grab('net.sourceforge.htmlunit:htmlunit:2.8')@GrabExclude('xml-apis:xml-apis')

GRABCONFIG@GrabConfig(systemClassLoader=true)@Grab(group='mysql', module='mysql-connector-java', version='5.1.6')

GrabConfigsystemClassLoader (boolean)

using the System-ClassLoaderinitContextClassLoader (boolean)

ContextClassLoader = CL of the current threadautoDownload (boolean)

automatic downloadingdisableChecksums (boolean)

checking checksums

PROXY-CONFIGURATION$ groovy -Dhttp.proxyHost=<host> -Dhttp.proxyPort=<port> -Dhttp.proxyUser=<user> -Dhttp.proxyPassword=<user> yourscript.groovy

JAVA_OPTS = -Dhttp.proxyHost=<host> -Dhttp.proxyPort=<port> -Dhttp.proxyUser=<user> -Dhttp.proxyPassword=<user>

QUESTIONS ?Alexander (Sascha) Klein

 codecentric AG

Curiestr. 270563 Stuttgart

 tel +49.711.67400-328

mobile [email protected]

@saschaklein 

http://www.codecentric.dehttp://blog.codecentric.de