How to run perl script with multiple args from python script - python

I made a python code that must sequentially execute a series of perl commands on the PC shell, the problem is that I did not realize that to send these scripts I have to add parameters (i have n_params), advice?
example command to send
perl [file_name.pl] [params]
To run these commands on the windows CMD I am using os and subprocess
python code example
# command = perl [file_name.pl] [params]
# path = location/of/where/the/pl/file/is/saved
perl_script = subprocess.Popen(["C:\\Perl64\\bin\\perl.exe",path + command], stdout=sys.stdout)
perl_script.communicate()
But running the script like this, the code gets me wrong because it says it can't find the filename in the specific directory

This argument to Popen()
["C:\\Perl64\\bin\\perl.exe", path + command]
does not look correct since you wrote that command is perl [file_name.pl] [params]. Instead try:
p = subprocess.Popen(["C:\\Perl64\\bin\\perl.exe", path+"file_name.pl", "param1", "param2", ...])

Related

Using WSL bash from within python

I'm using windows 10 and while working on a new project, I need to interact with WSL(Ubuntu on windows) bash from within python (windows python interpreter).
I tried using subprocess python library to execute commands.. what I did looks like this:
import subprocess
print(subprocess.check_call(['cmd','ubuntu1804', 'BashCmdHere(eg: ls)']))#not working
print(subprocess.check_output("ubuntu1804", shell=True).decode())#also not working
The expected behavior is to execute ubuntu1804 command which starts a wsl linux bash on which I want to execute my 'BashCmdHere' and retrieve its results to python but it just freezes. What am I doing wrong ? or how to do this ?
Thank you so much
Found 2 ways to achieve this:
A correct version of my code looks like this
#e.g: To execute "ls -l"
import subprocess
print(subprocess.check_call(['wsl', 'ls','-l','MaybeOtherParamHere']))
I should have used wsl to invoke linux shell from windows aka bash then my command and parameters in separated arguments for the subprocess command.
The other way which I think is cleaner but may be heavier is using PowerShell Scripts:
#script.ps1
param([String]$folderpath, [String]$otherparam)
Write-Output $folderpath
Write-Output $otherparam
wsl ls -l $folderpath $otherparam
Then to execute it in python and get the results:
import subprocess
def callps1():
powerShellPath = r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe'
powerShellCmd = "./script.ps1"
#call script with argument '/mnt/c/Users/aaa/'
p = subprocess.Popen([powerShellPath, '-ExecutionPolicy', 'Unrestricted', powerShellCmd, '/mnt/c/Users/aaa/', 'SecondArgValue']
, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = p.communicate()
rc = p.returncode
print("Return code given to Python script is: " + str(rc))
print("\n\nstdout:\n\n" + str(output))
print("\n\nstderr: " + str(error))
# Test
callps1()
Thank you for helping out
What about:
print(subprocess.check_call(['ubuntu1804', 'run', 'BashCmdHere(eg: ls)'])) #also try without "run" or change ubuntu1804 to wsl
Or
print(subprocess.check_call(['cmd', '/c', 'ubuntu1804', 'run', 'BashCmdHere(eg: ls)']))#also try without "run" or change "ubuntu1804" to "wsl"
# I think you need to play with quotes here to produce: cmd /c 'ubuntu1804 run BashCmdHere(eg: ls)'
First, try to call your command from cmd.exe to see the right format and then translate it to Python.
os.system('bash')
I figured this out by accident.

How to run a powerShell script from a python file

I couldn't find much information on this unfortunately, but I wish to run a powerShell script from a python file I've written. I want the user to actually see the powerShell script being run and the user can enter inputs that the powerShell script requires from python. I am using pyCharm as an IDE.
When I run the script to call this powerShell script, it gives me this error:
File "C:\TestAutomation\eFuse\eFuse.ps1", line 19
SyntaxError: Non-ASCII character '\xc2' in file C:\Test\eK\eK.ps1 on line 19, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
Here is the relevant part of the code:
elif switch_result == "eTool":
subprocess.call(['python', 'C:\\TestAutomation\\eFuse\\eFuse.ps1'], stdout=sys.stdout)
This elif statement is a part of other if/elif statements that run other python files using the subproccess module, but for some reason I can't get this powerShell file to be run. Any advice is appreciated. Thank you
First, you should already know .py file's interpreter is python.exe
So, it's easy to understand .ps1 file's interpreter is powershell.exe, not python.exe
I just copy & paste from yours, your code should look like following,
subprocess.call('powershell.exe -File "C:\\TestAutomation\\eFuse\\eFuse.ps1"', stdout=sys.stdout)
Details about powershell.exe -?
You can do following for provide input from user to PS (powershell) script from python :
1) Create parameterised powershell script
2) Take input in python and set it as PS script parameter.
3) run/execute the script with given params.
Here is the sample to run powershell script from python with param. Its a python code :
* Hope you have the PS script with parameters.
import subprocess
params = ['param1', 'param2'] # POWERSHELL SCRIPT PARAMETERS ( optional )
script_path = "C:\\PowershellScripts\\test.PS1" # POWERSHELL SCRIPT PATH
commandline_options = ["Powershell.exe", '-ExecutionPolicy', 'Unrestricted', script_path] # INITIALIZING COMMAND
for param in params: # FOREACH LOOP OF PARAMETERS
commandline_options.append(param) # ADDING SCRIPT PARAMETERS TO THE COMMAND
result = subprocess.run(commandline_options, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True) # RUN THE SCRIPT USING SUBPROCESS WITH PARAMS
print(result.returncode) # PRINT THE RETURN CODE FROM POWERSHELL SCRIPT
print(result.stdout) # PRINT THE STANDARD OUTPUT FROM POWERSHELL SCRIPT
print(result.stderr) # PRINT THE STANDARD ERROR FROM POWERSHELL SCRIPT
You can see the output of python if it exist ( if there is no error in powershell script. you will not get any output from last line )

Execute windows shell command and process output variables

In Python 3.7 running on Windows, what specific syntax is required to:
1. Navigate to a directory containing a terraform program
2. Execute "terraform apply -auto-approve" in that target directory
3. Extract the resulting output variables into a form usable in python
The output variables might take the form:
security_group_id_nodes = sg-xxxxxxxxxx
vpc_id_myvpc = vpc-xxxxxxxxxxxxx
Want to be using windows cmd style commands here, NOT powershell.
My first failed newbie attempt is:
import os
os.chdir('C:\\path\\to\\terraform\\code')
from subprocess import check_output
check_output("terraform apply -auto-approve", shell=True).decode()
Not sure about your output, but subprocess could definitely make the trick.
Try something like:
command = 'terraform apply -auto-approve'
TARGET_DIR = 'E:\Target\Directory'
subprocess_handle = subprocess.Popen(shlex.split(command), cwd=TARGET_DIR, shell=False, stdout=subprocess.PIPE)
subprocess_handle.wait()
result = subprocess_handle.communicate()[0]
print(result)
Worked for me once, just play around with params.
UPD: Here I assume that "terraform" is an executable.

Using Osgeo4w shell via. python script

I'm trying to write a script that creates multiple ogr2ogr calls to a WFS service (in a loop). For some reason i can't use the osgeo lib (it's a work computer, with limited access..), so i figured i would give the Subprocess lib a try.
My though process so far is:
open OSGeo4W shell
transfer string from script to shell command line
loop for multiple ogr2ogr calls
Code:
import subprocess
p = subprocess.Popen(r'C:\Program Files\QGIS 2.18\OSGeo4W.bat',
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
call = 'ogr2ogr -f "CSV" "folder_on_pc" WFS:"dbname" -sql "SELECT * from
specific_layer where attribute>=20180311 ORDER BY attribute"'
subprocess.check_call(call, shell=True)
output = p.communicate(call)[0]
I know the ogr2ogr call works, but can't seem to make the command line 'type it'. If this is a completly wrong approach, please tell me. I appriciate all help.

How do I know what python scripts are running in Windows?

As I mentioned above, is there a way to find out what python scripts are running in Windows?
If you have PowerShell installed, you can get that information by using Windows Management Instrumentation (WMI) and some scripting...
Open the PowerShell and use these two lines, it should could you started:
> $pys = get-wmiobject Win32_process -filter "Name='python.exe'"
> $pys.CommandLine
This will show you the command line arguments used to start the python process, which should contain the name of the main script file ran by Python. For a test program I have, it displays the following:
"C:\Python27\python.exe" "D:\Projects\wait.py"
In case you have multiple scripts running, the var $pys will be an array, so to access it you'll have to access the individual elements like so:
> $pys[0].CommandLine
EDIT: Or you could do it all in one single line, again in PowerShell:
> get-wmiobject Win32_process -filter "Name='python.exe'" | foreach -process {$_.CommandLine}
I hope you get the general idea.
This is what you need
import subprocess
p = subprocess.Popen(["powershell.exe", "get-wmiobject Win32_process -filter \"Name='python.exe'\"| foreach -process {$_.CommandLine}"], stdout=subprocess.PIPE)
out, err = p.communicate()
service = "file.py"
if service in str(out):
print('Service Is Running')

Categories