Shell Command with SoapUI groovy - groovy

So I'm trying to run a shell script on an automated SoapUI project which is execute in continuous integration. I need to send a few parameters and an SQL query to the script so I'm trying to execute a command similar to this:
/path/to/file.sh param1 param2 "sql query"
If I log the command and execute it manually it works perfectly but when groovy runs it the "sql query" argument is split into multiple arguments for every space.
I've tried running the command with
String command = "/path/to/file.sh param1 param2 \"sql query\""
def proc = command.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(5000)
I'm not getting what I'm doing wrong.
Best regards

In Grooy also arrays (arrays are internal lists) have a execute method. It's usually much safer to execute commands over arrays.
def command = ['/path/to/file.sh', 'param1', 'param2', 'sql query']
def proc = command.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(5000)

Related

How to exclude $ from process builder String parameter, to execute a shell command

I am trying to escape the "$" symbol when executing a echo $! command in java.
static def execSync(String command) throws Exception {
log.info("exec(" + command + ")")
String[] splited = command.split("\\s+")
def listCommand = Arrays.asList(splited)
ProcessBuilder processBuilder = new ProcessBuilder()
processBuilder.command(listCommand)
return processBuilder.start()
}
execSync("echo \$!") // returns $! when i'd like a pid
I have identified the problem to be in the command that is executed (ie: the code above) and not from my way of getting the stdout of the command (outputstream blabla). If your are absolutely sure it's not, i'll show more.
When i execute on my system (centOs 7) "echo $!" i obviously get a pid, for instance : 2626.
I would mostly like to know if there is a way to do a "echo $!" like on the system with a string in my function ? (regex or other stuff)
Otherwise,
ProcessBuilder.start returns a Process but doesn't seem to have a method to get the pid, only exitReturn, out/in/error stream... Since I execute the previous command with the method shown above, i though i could get the pid with a linux command.
So, is there a way to get the pid of the previous process ? (not realy what i seek but i can manage if there is no other way)
I'm stuck with java 8, when java 9 has a method "getPid"
If you .execute() or use the ProcessBuilder directly, you can not directly use shell features. It just allows to spawn processes with arguments. You have to start a shell and make it execute your shell "script" (command). E.g.
def listCommand = ["/bin/sh", "-c", command]

groovy "...".execute() works on windows but fails on linux

while this line works fine on windows on my linux box it returns exit code 1.
"gnuplot -e \"set output '${imageFile.toString()}'; filename='${dataFile.toString()}'; ${args}\" \"${plotFile.toString()}\"".execute()
But if I execute just this from the terminal everything works.
gnuplot -e "set output '/tmp/hrp-current.jpg'; filename='/tmp/a731265b-3736-4bb9-acf4-b92c1a09b999.csv'; " "/tmp/hrp/build/groovy/../gnuplot/hrp-current.gnuplot"
What am I missing here? It somehow has to do with the fact that gnuplot writes to a file because `some_command > some.file" also fails on linux with exit code 1 while it would work fine on windows.
.execute() on a String just splits on whitespace. You also don't need to quote the params for execution (you need to that for the shell). So execute an list of params instead:
["gnuplot", "-e", "set output '${imageFile.toString()}'; filename='${dataFile.toString()}'; ${args}", plotFile.toString()].execute()
Indeed it is some file writing issue so I need gnuplot to pipe its outout to stdout and then consume it from my groovy script where I read the outputstream and then save it to a file:
def out = new ByteArrayOutputStream()
def err = new ByteArrayOutputStream()
process.waitForProcessOutput(out, err)

Assign Linux Command to Variable in Groovy

I'm attempting to run a linux command, curl, through groovy, and would like the output to be assign to a variable. I'd like to do this, so I can extract specific data from the curl output, and use in in m y groovy script.
Any ideas, how I can do this.
I've tried,
def after = "curl \"https://test.com\"".execute()
def after = "curl \"https://test.com\"".execute().text
but the variable is always empty. Any help would be appreciated.
linux command with spaces needs to be separated.
["/bin/sh", "-o", "your_command"].execute()
In your case it would be something like below:
["curl", "https://test.com"].execute()
OR
def after = ["curl", "https://test.com"].execute().text
Try and see if it works.

Groovy Can't Exec wmic on winserver 2003

Any clue as to what's my blocker in an attempt to run an external process via groovy on windows 2003?
When I execute "wmic process get processid" on commandline with same path as groovy exec this works producing output. On winserver 2008, this works. On 2003 it doesn't even if I add "cmd /c ..." I also tried using "wmic quit" and I continue to get a non zero result code. So, I don't think groovy can exec wmic on this version of windows.
I'm baffled as to what is different between the two environments.
StringBuffer output = new StringBuffer()
StringBuffer err = new StringBuffer()
def process = "wmic process get processid".execute()
process.consumeProcessOutput(output,err)
process.waitForOrKill(7000)
println "Output:\n${output.size()}\nErr:\n${err.size()}\n${output}\n${err}"

STDOUT does not work programmatically via Groovy API

Using espeak command to generate an audio
espeak "Hello Mr. Toumi" --stdout > /tmp/audio123.wav
When i run this command using terminal , it works fine .
Prepare now in API for this command in Grails Service
#EspeakService.groovy
File speak(String message){
Process pr='espeak "'+message+'" --stdout > '+filePath(message);
pr.waitFor()
return new File(filePath(message));
}
When i run : espeakService.speak('Hello Mr. Toumi') , there is no file generated and also no error message displayed .
Any idea : Why does it not work programmatically ?
Java's external process execution mechanism is not a shell and doesn't support redirection using > like that. You should use a ProcessBuilder and do the redirection with that:
ProcessBuilder pb = new ProcessBuilder("espeak", message, "--stdout")
File out = new File(filePath(message))
pb.redirectOutput(out)
pb.redirectError(ProcessBuilder.Redirect.INHERIT)
pb.start().waitFor()
return out
redirections like > are done by shell. either use ['sh', '-c', 'espeak ...'].execute(). or just pick up the stdout from the process, which would save you from dealing with a file. e.g.
def p = "echo -n 666".execute()
p.waitFor()
assert p.in instanceof InputStream
assert p.in.text == "666"

Resources