Start EXE-file with parameters via Groovy (problems with return value) - groovy

I am trying to start an external executable file via Groovy but got some problems with it! I just want to start the rs.exe with several parameters to create a PDF-file using the SSRS.
But as soon as I try to get the return value/exit-code it doesn't work anymore! But I want to grab the generated file and add it to a database, so I need a return value to know when its generated. This works totally fine for generating:
def id = 1
def cmd = """ C://Program Files (x86)//...//rs.exe
-i C:\\export.rss
-s http://localhost/ReportServer_SQLEXPRESS
-v ID=${id}
-e Exec2005 """
def proc = cmd.execute()
But I don't get any return value/exit-code. I already tried different way, e.g.
proc.waitFor()
but I or
cmd.execute().value
but nothing worked. When I start the rs.exe with all my provided data in Windows I get the return "Process succesfully ended". Any Groovy-specialists here that can help me out?

Try executing command when it's defined in the following way:
def cmd = ['cmd', '/c', 'C://Program Files (x86)//...//rs.exe', '-i', 'C:\\export.rss', '-s', 'http://localhost/ReportServer_SQLEXPRESS', '-v', "ID=${id}", '-e', 'Exec2005']
def proc = cmd.execute()

I was able to run it now and get the exit-code. But without those escape forward-slashes I wasn't able to let it run. To get the exit-codes I just used "proc.text" and it works perfectly now.
It was working before but I didn't know how to get the exit-codes, ".text" solved it completely. Thanks for your help!

Related

Python 3.8: How does one pass a variable to a Windows CMD subprocess?

Up front confession... I'm a python neophyte. Please forgive any ignorance on my part.
As just a way to learn more, I'm trying to write a script that will take my latest Quicken backup and with 7-Zip, create a compressed and encrypted file with a timestamp in the name. I then want to copy it two two locations.
I have succeeded up the the name part. I've created a variable for the time the script starts and I want to append this to a base file name, but I don't seem to be able to do it. When I've tried, the script runs, but nothing is ever created, no compressed file that is. If I remove what I have with regard to the variable for the filename, I do get a compressed and encrypted file as expected.
Here is what I have so far. The print commands are just there for me making sure I've done the 'today' and 'newfile' variables correctly. Also, I'm doing the testing with just an empty .docx file so that it processes quicker.
Thanks in advance for any/all help or suggestions. I really appreciate it.
from datetime import datetime
from pathlib import Path
today = datetime.now()
print(today.strftime('%Y-%m-%d %H:%M:%S'))
newfile = 'Q2020_' + (today.strftime('%m-%d-%Y_%H%M%S'))
print(newfile)
os.chdir('D:/Quicken Backups')
print(os.getcwd())
import subprocess
cmd= ['C:\\Program Files\\7-Zip\\7z.exe', 'a', '-t7z', '-mx9', '"D:\\Quicken Backups\\Quicken2020\\" + newfile ".7z"', '-ppassword', '-mhe', 'D:\\Quicken Backups\\test.docx']
subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
Have you thought about using a python package made for zipping, like zipfile?
This way you dont need to deal with opening a subprocess
import zipfile
dest_zip_folder = '2020_backup.zip' # new file name
file_to_zip = 'D:\\Quicken Backups\\test.docx'
zipfile.ZipFile(dest_zip_folder, mode='w').write(file_to_zip)
If you dont want to use that way, I see an error in your code.
You are missing a + after newfile
cmd = [ ...., .... + newfile + '.7zip', ... ]
Also give subprocess.call() a try
import subproccess
cmd = [. . . . . .]
subprocess.call(cmd)
It took a LOT of mucking around with Windows variables syntax and running the subprocess a little differently, but I finally got the thing working, outputting an encrypted file with a date/time stamp in the file name.
For troubleshooting I added the /K to the cmd command so that the window would not close upon completion. This was a HUGE help in trouble shooting this.
Thanks to everyone who even looked at my posted. I hope someday this thread will help someone else!
import os
from pathlib import Path
os.chdir('D:/Quicken Backups')
print(os.getcwd())
import subprocess
cmd = subprocess.Popen('cmd.exe /K ""C:\\Program Files\\7-Zip\\7z.exe" a -t7z -mx9 "D:\\Quicken Backups\\Quicken2020\\Q2020_%DATE:~4,2%-%DATE:~7,2%-%DATE:~-4%_%TIME:~0,2%%TIME:~3,2%%TIME:~8%.7z" -ppassword -mhe "D:\\Quicken Backups\\test.docx"')

Running a cmd command in Python

I am having a problem that I have been spending quite a lot of time on. I have a few lines of code that I run through a bat file, that I would like to run from a Python script instead. This is so that I can feed in variables and create the cmd string throug Python code.
The code is used to run Tableau bridge client to sync a data extract. This is the code and it works when I run it from a BAT file:
#echo off
cd C:\Program Files\Tableau\Tableau 10.3\bin
tableau refreshextract --server https://dub01.online.tableau.com --username "username" --password "password" --site "sitename" --project "project name" --datasource "datasource name" --source-username sql_backend_username --source-password sql_backend_password
I understand that the first line sets the working directory to the folder where Tableau is installed. And the second line does the refreshing.
I have been trying to make this work in Python by just doing something like this:
import os
os.chdir("C:\\Program Files\\Tableau\\Tableau 10.3\\bin")
os.system("tableau -cmd_string_from_above
but all that this does is run the Tableau client, and not the process running the extract. I have been looking at some examples using popen but all of that code is so complex that I dont understand how it actually works.
Hope someone can help me out.
If it works as a bat file, try running that from python.
os.system("start mybatch.bat")
I would recommend you look at the module subprocess
as and example:
subprocess.call(["C:\\Program Files\\Tableau\\Tableau 10.3\\bintableau", "refreshextract", "etc. etc."])
a simpler example:
from subprocess import call
call(["ping", "localhost"])
Ok so building on the code/methods other sugested here I did manage to get it working. It might be kind if a "hacky" solution, but it looks like it is working ok. Here is the example
import json
import os
import subprocess
def refresh_extract(project_name, datasource_name):
#Json file containing most of the variables used
params = json.load(open('all_paths.json'))
server = params['tableau']['server']
username = params['tableau']['username']
password = params['tableau']['password']
site = params['tableau']['site']
source_username = params['tableau']['source-username']
source_password = params['tableau']['source-password']
filepath = "Path to bat file that is called"
executable = os.path.join(filepath, 'tableau_refresh.bat')
#Set the working dir to dir where tableau files used for the call is stored, this is the "hacky" part, needed for the bat to find tableau
os.chdir("C:\\Program Files\\Tableau\\Tableau 10.3\\bin")
p = subprocess.Popen([executable, '%s' %server, '%s' %username, '%s' %password, '%s' %site, '%s' %project_name, '%s' %datasource_name, '%s' %source_username, '%s' %source_password])
return 0
if __name__ == "__main__":
project_name = "project_name"
datasource_name = "data_source_name"
run = refresh_extract(project_name, datasource_name)
Thanks a lot to everyone that helped me figure it out!
This is the code for the bat file just in case it could help someone else
#echo off
#this seems not to be working, therefore I set the working did using
#os.chdir
cd C:\Program Files\Tableau\Tableau 10.3\bin
tableau refreshextract --server %1 --username %2 --password %3 --site %4 --
project %5 --datasource %6 --source-username %7 --source-password %8
PAUSE

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)

Can i access the variables of the python script after run that python script with console?

I run the python script using terminal command
python3 myScript.py
It's simply run my program but if i want to open python console after complete run of my script so that i can access my script's variables.
So, What should i do ? and How can i get my script's variables after run the code using terminal ?
Open a python terminal (type 'python' in cmd);
Paste this (replace 'myScript.py' with your script filename):
def run():
t = ""
with open('myScript.py') as f:
t = f.read()
return t
Type exec(run()). Now you will have access to the variables defined in myScript.py.
I needed to do this so I could explore the result of a request from the requests library, without having to paste the code to make the requests every time.
Make the program run the other program you want with the variables as arguments. For example:
#program1
var1=7
var2="hi"
import os
os.system("python %s %d %s" % (filename, var1, var2))
#program2
import sys
#do something such as:
print(sys.argv[1]) #for var1
print(sys.argv[2]) #for var2
Basically, you are running program2 with arguments that can be referenced later.
Hope this helps :)

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.

Resources