Escaping double-backslash in groovy - groovy

I have a Groovy script that should read a value from a registry key, on a remote machine. When I run reg query command on the local machine, or from another machine on the network, I get back the correct value. I also get the correct value when I run the Groovy script against the local machine (removing "\\' + hostname + '\").
When I run the code listed below, I get the following error:
java.io.IOException: Cannot run program "\HKEY_LOCAL_MACHINE\SOFTWARE\Application\": CreateProcess error=2, The system cannot find the file specified
This leads me to believe that I am failing to escape the path correctly. If that's right, how should I escape a double-backslash?
Here is the script:
def hostname = '10.1.1.2'
def outVal = ''
try {
output = 'reg query \\\\' + hostname + '\\HKEY_LOCAL_MACHINE\\SOFTWARE\\SynAEM\\UDF1 -v PatchGroup'.execute().text
outVal = output.tokenize(' ')[-1]
}
catch(Exception e) {
outVal = 'NotSpecified'
println e
}
println 'PatchGroup=' + outVal
return 0

Your problem has nothing to do with backslashes. It's to do with precedence. What you wrote is equivalent to:
output = 'reg query \\\\' + hostname +
('\\HKEY_LOCAL_MACHINE\\SOFTWARE\\SynAEM\\UDF1 -v PatchGroup'.execute().text)
The execute() method was trying to run the last string, ie the registry name. What you need is:
output = ('reg query \\\\' + hostname + '\\HKEY_LOCAL_MACHINE\\SOFTWARE\\SynAEM\\UDF1 -v PatchGroup').execute().text
or, possibly a bit clearer:
output = "reg query \\\\$hostname\\HKEY_LOCAL_MACHINE\\SOFTWARE\\SynAEM\\UDF1 -v PatchGroup".execute().text

Related

Passing multiple params to a cmd line argument via Powershell - what quotes to use and when

When in Powershell I can run the following command
.\exiftool.exe '-GPSLatitude*=56.9359839838' '-GPSLongitude*=-4.4651045874' DSC01008.JPG '-overwrite_original_in_place'
This works just fine, and the placement of single quotes around those params are required. I went through various iterations of different placements and the above is the only way I could get it to work.
My issue is -> That I'm trying to replace those values with programmatic values. As in something like the following.
$lat = 56.9359839838
$lon = -4.4651045874
$fileName = 'DSC01008.JPG'
.\exiftool.exe -GPSLatitude*=$lat -GPSLongitude*=$lon $fileName '-overwrite_original_in_place'
I've gone through numerous attempts with single/backtick/double quotes, trying to concatenate and anything else I can think of - but that magic format hasn't appeared!
Any thoughts on what I am doing wrong?
As an example I thought this was really work, yet didn't. But it matches up with the command that does when it's hard coded.
EDIT/Update -
The * are required inside the command, otherwise it doesn't work. They are used to get around not passing in reference locators.
If you were to run these commands in PS, then these are the errors that you get.
cmd ->
.\exiftool.exe "-GPSLatitude*=$lat" "-GPSLongtitude*=$lon" $FileName
error ->
No Error, but the file does not get any GPS tags. Nothing actually modified.
cmd ->
$combLat = "`'-GPSLatitude*=$lat`'" # + "
$combLon = "`'-GPSLongitude*=$lon`'" # + "'"
$combined = "$combLat $combLon $fileName"
# $combined will output the following: '-GPSLatitude*=-3.4651045874' '-GPSLongitude*=55.9359839838' 'E:\CameraAddGPS\TestFolder\DSC01010.JPG'
.\exiftool.exe $combined
error ->
.\exiftool.exe : Wildcards don't work in the directory specification
At E:\CameraAddGPS\TestFolder\demo.ps1:25 char:1
+ .\exiftool.exe $combined
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Wildcards don't...y specification:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
No matching files
Update 2 -
This will work, but I do not want to update the image twice.
$combLat = '-GPSLatitude*=' + $lat
$combLon = '-GPSLongitude*=' + $lon
.\exiftool.exe $combLat $fileName '-overwrite_original_in_place'
.\exiftool.exe $combLon $fileName '-overwrite_original_in_place'
The problem is that the latitude and longtitude argumets are "attached" directly to the -GPSLatitute* and -GPSLongtitude* parameter names after the = sign. (The - initial character prevents PowerShell from invoking variable expansion - see GitHub issue #14587.)
One way to work around this is to wrap the -GPSLatitude* and -GPSLongtitude* parameters in " quotes; e.g.
.\exiftool.exe "-GPSLatitude*=$lat" "-GPSLongtitude*=$lon" $FileName -overwrite_original_in_place
Another way is to prefix the - character with a backquote (`); e.g.:
.\exiftool.exe `-GPSLatitude*=$lat `-GPSLongitude*=$lon $fileName -overwrite_original_in_place
I prefer the first variation as it seems more readable to me.
Aside #1: There's no need for the single ' quotes around that last parameter. They don't hurt, but they don't do anything, either.
Aside #2: You can see the actual command line that PowerShell is running if you prefix your command with the getargs command available here:
https://github.com/Bill-Stewart/getargs/releases
The getargs utility outputs the actual command line without any parsing or interpretation and will show the actual command that PowerShell will run.

How do I run an external file in soapui and take the output and set it as header

I would like to run an external .bat file using groovy script in soapUI. also would like to use the output generated from the external file as the value for the header
here is the script that I am using to run the bat file
String line
def p = "cmd /c C:\\Script\\S1.bat".execute()
def bri = new BufferedReader (new InputStreamReader(p.getInputStream()))
while ((line = bri.readLine()) != null) {log.info line}
here is the content of the bat file
java -jar SignatureGen.jar -pRESOURCE -nRandomString -mGET -d/api/discussion-streams/metadata -teyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJjbGllbnQiOiIxIiwicm9sZSI6IllGQURNSU4iLCJleHAiOjI3NTgzMjU2MDIsInRpIjo3MjAwNiwiaWF0IjoxNTU4MzI1NjAyLCJwZXJzb24iOiI1In0.bbci7ZBWmPsANN34Ris9H0-mosKF2JLTZ-530Rex2ut1kjCwprZr_196N-K1alFBH_A9pbG0MPspaDOnvOKOjA
The following code:
def p = "ls -la".execute()
def err = new StringBuffer()
def out = new StringBuffer()
p.waitForProcessOutput(out, err)
p.waitForOrKill(5000)
int ret = p.exitValue()
// optionally check the exit value and err for errors
println "ERR: $err"
println "OUT: $out"
// if you want to do something line based with the output
out.readLines().each { line ->
println "LINE: $line"
}
is based on linux, but translates to windows by just replacing the ls -la with your bat file invocation cmd /c C:\\Script\\S1.bat.
This executes the process, calls waitForProcessOutput to make sure the process doesn't block and that we are saving away the stdout and stderr streams of the process, and then waits for the process to finish using waitForOrKill.
After the waitForOrKill the process has either been terminated because it took too long, or it has completed normally. Whatever the case, the out variable will contain the output of the command. To figure out whether or not there was an error during bat file execution, you can inspect the ret and err variables.
I chose the waitForOrKill timeout at random, adjust to fit your needs. You can also use waitFor without a timeout which will wait until the process completes, but it is generally better to set some timeout to make sure your command doesn't execute indefinitely.

I want to exception of linux command

I want to control on python
try catch wifi list and connect to catching wife name and password
but I use linux command so I can't care linux error window
I want to check password in python
when i set wrong password, open Network manager.
What should i do?
import commands
def space_filter(x):
if x == ' ':
pass
else:
return x
#fail, output = commands.getstatusoutput("nmcli dev wifi list")
test= commands.getoutput("nmcli dev wifi list")
test1=test.split(' ')
print test
print test1
test2 = []
test1 = list(filter(space_filter, test1))
#print test1
for x in range(len(test1)):
if test1[x] == '\n*' or test1[x] =='\n':
test2.append(test1[x+1])
#print test2
try:
result = commands.getoutput("nmcli d wifi connect " + test2[0] + " password 1234")
print result
except:
print "password is wrong"[enter image description here][1]
Exceptions are a language specific construct to catch abnormal/error situations. The correct way to check error conditions in shell commands is the return value.
Use the getstatusoutput function in commands module to catch the return value along with the output. In your case, you would need to parse the output along with the return code to get the reason for failure since nmcli only distinguishes between certain kinds of failure. - https://developer.gnome.org/NetworkManager/stable/nmcli.html
(status, output) = commands. getstatusoutput("nmcli d wifi connect " + test2[0] + " password 1234")
if not status:
print "error"

Using Groovy, how can we call a python script, in windows, with one argument

I need to run a python script in windows system using groovy script.
Example:
python.exe c:/main.py argument1
I am new to groovy and I don't know, how to do it.
Please share me groovy syntax to run python as mentioned in the above example
I am preparing this script for jenkins.
so, "command".execute() is the right start.
But this command only starts a thread and you don't wait for the result.
try this code:
def task = "python main.py".execute()
task.waitFor()
println task.text
These lines start the execution, wait for it to finish and print the result.
To output already during execution for longer running tasks, I've written myself a small helper:
String.metaClass.executeCmd = { silent ->
//make sure that all paramters are interpreted through the cmd-shell
//TODO: make this also work with *nix
def p = "cmd /c ${delegate.value}".execute()
def result = [std: '', err: '']
def ready = false
Thread.start {
def reader = new BufferedReader(new InputStreamReader(p.in))
def line = ""
while ((line = reader.readLine()) != null) {
if (silent != false) {
println "" + line
}
result.std += line + "\n"
}
ready = true
reader.close()
}
p.waitForOrKill(30000)
def error = p.err.text
if (error.isEmpty()) {
return result
} else {
throw new RuntimeException("\n" + error)
}
}
This defines through meta programming a new method on String called executeCmd.
Put this on top of your file and then your line
"python c:/main.py".executeCmd()
This should show you all output during execution and it will help you to handle the paramaters the correcct way through the "cmd /c"-prefix. (If you just call execute on a string, you often run into problems with spaces and other characters in your command.
If you already have the parameters as a list and need some code which also runs on a *nix machine, try to call execute() on a list:
["python", "c:/main.py"].execute()
hope this helps
ps: http://mrhaki.blogspot.com/2009/10/groovy-goodness-executing-string-or.html

Use groovy script output as input for another groovy script

I'll apologise in advance, I'm new to groovy. The problem I have is I have 3 groovy scripts which perform different functionality, and I need to call them from my main groovy script, using the output from script 1 as input for script 2 and script 2's output as input for script 3.
I've tried the following code:
script = new GroovyShell(binding)
script.run(new File("script1.groovy"), "--p", "$var" ) | script.run(new File("script2.groovy"), "<", "$var" )
When I run the above code the first script runs successfully but the 2nd doesn't run at all.
Script 1 takes an int as a parameter using the "--p", "$var" code. This runs successfully in the main script using: script.run(new File("script1.groovy"), "--p", "$var" ) - Script 1's output is an xml file.
When I run script.run(new File("script2.groovy"), "<", "$var" ) on its own in the main groovy script nothing happens and the system hangs.
I can run script 2 from the command line using groovy script2.groovy < input_file and it works fine.
Any help would be greatly appreciated.
You cannot pass the < as an argument to the script as redirection is handled by the Shell when you run things from the command line...
Redirecting output from Scripts into other scripts is notoriously difficult, and basically relies on you changing System.out for the duration of each script (and hoping that nothing else in the JVM prints and messes up your data)
Better to use java processes like the following:
Given these 3 scripts:
script1.groovy
// For each argument
args.each {
// Wrap it in xml and write it out
println "<woo>$it</woo>"
}
linelength.groovy
// read input
System.in.eachLine { line ->
// Write out the number of chars in each line
println line.length()
}
pretty.groovy
// For each line print out a nice report
int index = 1
System.in.eachLine { line ->
println "Line $index contains $line chars (including the <woo></woo> bit)"
index++
}
We can then write something like this to get a new groovy process to run each in turn, and pipe the outputs into each other (using the overloaded or operator on Process):
def s1 = 'groovy script1.groovy arg1 andarg2'.execute()
def s2 = 'groovy linelength.groovy'.execute()
def s3 = 'groovy pretty.groovy'.execute()
// pipe the output of process1 to process2, and the output
// of process2 to process3
s1 | s2 | s3
s3.waitForProcessOutput( System.out, System.err )
Which prints out:
Line 1 contains 15 chars (including the <woo></woo> bit)
Line 2 contains 18 chars (including the <woo></woo> bit)
//store standard I/O
PrintStream systemOut = System.out
InputStream systemIn = System.in
//Buffer for exchanging data between scripts
ByteArrayOutputStream buffer = new ByteArrayOutputStream()
PrintStream out = new PrintStream(buffer)
//Redirecting "out" of 1st stream to buffer
System.out = out
//RUN 1st script
evaluate("println 'hello'")
out.flush()
//Redirecting buffer to "in" of 2nd script
System.in = new ByteArrayInputStream(buffer.toByteArray())
//set standard "out"
System.out = systemOut
//RUN 2nd script
evaluate("println 'message from the first script: ' + new Scanner(System.in).next()")
//set standard "in"
System.in = systemIn
result is: 'message from the first script: hello'

Resources