I am trying to develop python plugin on QGIS and I am trying to execute binary programs using subprocess :
program = os.path.join(self.tranusConf.tranusBinPath,'pasos' + self.extension)
if not os.path.isfile(program):
logging.error('The <pasos> program was not found in %s'%self.tranusBinPath )
return 0
outpasos = os.path.join(self.resultDirectory, "outpasos.txt")
outpasoserr = os.path.join(self.resultDirectory, "outpasoserr.txt")
args = [program, self.tranusConf.scenarioId, " "]
result = subprocess.Popen(args,stdout=open(outpasos, "w"), stderr = open(outpasoserr, 'w'), close_fds = False, cwd = self.tranusConf.workingDirectory) # Success!
return 1
I get this problem:
An error has occurred while executing Python code:
WindowsError: [Error 6] Descripteur non valide Traceback (most recent call last): File "C:/Users/emna/.qgis2/python/plugins\OptionsTRANUS\launch_tranus_dialog.py", line 109, in run_tranus
interface.runTranus(tab.spin_box.value())
File "C:/Users/emna/.qgis2/python/plugins\OptionsTRANUS\LcalInterface.py", line 426, in runTranus
self.runPasos()
File "C:/Users/emna/.qgis2/python/plugins\OptionsTRANUS\LcalInterface.py", line 311, in runPasos
result = subprocess.Popen(args,stdout=open(outpasos, "w"), stderr = open(outpasoserr, 'w'), close_fds = False, cwd = self.tranusConf.workingDirectory) # Success!
File "C:\OSGEO4~1\apps\Python27\lib\subprocess.py", line 703, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\OSGEO4~1\apps\Python27\lib\subprocess.py", line 839, in _get_handles
p2cread = self._make_inheritable(p2cread)
File "C:\OSGEO4~1\apps\Python27\lib\subprocess.py", line 878, in _make_inheritable
_subprocess.DUPLICATE_SAME_ACCESS)
WindowsError: [Error 6] Descripteur non valide
I searched for others who have the same error, and they propose to invoke shell = True or use os.popen but it is not working.
For information, I am working on Windows 7 64 bits.
Solved : I added shell = True
proc = subprocess.Popen(args,shell=True,stdout=open(outimploc, 'w'), stderr=open(outimplocerr,'w'),stdin = subprocess.PIPE, cwd=self.tranusConf.workingDirectory).communicate()
I found a partial solution to my problem :
devnull = open(os.devnull, 'wb')
result = subprocess.Popen(args,stdout = open(outtrans, "w"), stderr = open(outtranserr,'w'),stdin=devnull, cwd = self.tranusConf.workingDirectory).communicate()
It works. but I am embarrased in my plugin with the multiple opens of windows cmd of the programs that are executed. This is not esthetically beautiful for my plugin.
Edit : the same with using stdin=subprocess.PIPE
Related
I try to execute command in cmd from Python and save the output. I have the following code:
import subprocess
import matplotlib.pyplot as pyplot
MyOut = subprocess.Popen("pytr portfolio",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout,stderr = MyOut.communicate()
chart_data = []
days = []
t = 0
new_char = stdout.split()
print(new_char)
netValue = float(new_char[new_char.index(b'netValue') + 2])
file = open('netValue.txt','a')
file.write(str(netValue))
file.write('\n')
file.close()
file = open('netValue.txt','r')
for line in file:
t += 1
print(line)
chart_data.append(line)
days.append(t)
file.close()
pyplot.plot(days,chart_data)
pyplot.title('depot_performance')
pyplot.show()
On my pc it works well but when I run this on my laptop i get the following error message:
Traceback (most recent call last):
File "c:\Users\dinok\OneDrive\Desktop\Python_Scripts\depot_statistics.py", line 9, in <module>
MyOut = subprocess.Popen("pytr portfolio",
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1776.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 969, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.1776.0_x64__qbz5n2kfra8p0\lib\subprocess.py", line 1438, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden
I thought it is path related so that the module is not found but was not able to find a solution. What could cause this problem and how to fixt it?
Python's subprocess.Popen first parameter should be a list, the executable and the executable arguments. To fix it just do like the following snippet:
MyOut = subprocess.Popen(["pytr", "portfolio"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
windows 7 python 2.7
when I use popen to open a process:
from ctypes import *
dldtool = cdll.LoadLibrary(r'main.dll')
cmd = "dld_tool -c {} -r programmer.bin -f {}".format(port,file)
print cmd
with LOCK:
process = Popen(cmd, stdout=PIPE)
while process.poll() is None:
out = process.stdout.readline()
if out != '':
print out
error occurs:
process = Popen(cmd, stdout=PIPE)
File "C:\Python27\lib\subprocess.py", line 390, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 640, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
The main.dll is in the working directory. should I change the code in python or change the any config?
You should use either the shell=True parameter if you want to pass the entire command with arguments as one string:
process = Popen(cmd, stdout=PIPE, shell=True)
or shlex.split to split your command line into a list (after importing shlex):
process = Popen(shlex.split(cmd), stdout=PIPE)
Otherwise the entire command line with arguments would be treated as one file name, and the system naturally would not be able to find it.
Objective: Converting ppt to pdf using python 3.6.1
Scenario: MS Office is not installed in windows server
Code used:
from subprocess import Popen, PIPE
import time
def convert(src, dst):
d = {'src': src, 'dst': dst}
commands = [
'/usr/bin/docsplit pdf --output %(dst)s %(src)s' % d,
'oowriter --headless -convert-to pdf:writer_pdf_Export %(dst)s %(src)s' % d,
]
for i in range(len(commands)):
command = commands[i]
st = time.time()
process = Popen(command, stdout=PIPE, stderr=PIPE, shell=True) # I am aware of consequences of using `shell=True`
out, err = process.communicate()
errcode = process.returncode
if errcode != 0:
raise Exception(err)
en = time.time() - st
print ('Command %s: Completed in %s seconds' % (str(i+1), str(round(en, 2))))
if __name__ == '__main__':
src = 'C:\xxx\ppt'
dst = 'C:\xxx\ppt\destination'
convert(src, dst)
Error Encountered:
Traceback (most recent call last):
File "C:/PythonFolder/ppt_to_pdf.py", line 134, in <module>
convert(src, dst)
File "C:/PythonFolder/ppt_to_pdf.py", line 123, in convert
process = Popen(command, stdout=PIPE, stderr=PIPE, shell=True) # I am aware of consequences of using `shell=True`
File "C:\Python 3.6.1\lib\subprocess.py", line 707, in __init__
restore_signals, start_new_session)
File "C:\Python 3.6.1\lib\subprocess.py", line 990, in _execute_child
startupinfo)
ValueError: embedded null character
Does anyone know how to fix this error?
Or any other python library that will help in this case.
Since you're running on Windows, the command /usr/bin/docsplit pdf --output %(dst)s %(src)s won't convert the PPT, since it seems it's for Linux. Popen might be having trouble handling that command, causing the error.
Converting a PPT to a PDF in the command line on Windows is kinda hard. I think your best bet is to install LibreOffice and run with headless mode. There's also a SuperUser question on it where the asker ends up using C# interop libraries, but I think that requires Microsoft Office to be installed.
Thanks.
How do I write a maven command in python? I saw this example online, but it doesn't seem to be working in Windows.
def local2(command, print_command=False):
from subprocess import Popen, PIPE
p = Popen(command, stdout=PIPE, stderr=PIPE)
if print_command: print " ".join(command)
output, errput = p.communicate()
return p.returncode, output, errput
def uploadQAJavaToNexus():
url = "example"
groupId = "example"
artifactId = "example"
repositoryId = "example"
# filePath =
version = "version"
status, stdout, stderr = local2([
"mvn",
"deploy:deploy-file",
"-Durl=" +url,
"-DrepositoryId=" +repositoryId,
"-Dversion=" + version,
"-Dfile=" + "path"
"-DartifactId=" + artifactId,
"-Dpackaging=" + "jar",
"-DgroupId" + groupId,
])
return status, stdout, stderr
UPDATE: This is the error I'm getting given below:
Traceback (most recent call last):
File "C:\PythonProject\src\Get.py", line 355, in <module>
uploadQAJavaToNexus()
File "C:\Get.py", line 250, in uploadQAJavaToNexus
"-DgroupId" + groupId,
File "C:\Get.py", line 227, in local2
p = Popen(command, stdout=PIPE, stderr=PIPE)
File "C:\Python27\lib\subprocess.py", line 710, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 958, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
I prefer to use fabric (http://www.fabfile.org/):
from fabric import local
def maven_start():
local('<cmd>')
$ fab maven_start
As I started asking on a previous question, I'm extracting a tarball using the tarfile module of python. I don't want the extracted files to be written on the disk, but rather get piped directly to another program, specifically bgzip.
#!/usr/bin/env python
import tarfile, subprocess, re
mov = []
def clean(s):
s = re.sub('[^0-9a-zA-Z_]', '', s)
s = re.sub('^[^a-zA-Z_]+', '', s)
return s
with tarfile.open("SomeTarballHere.tar.gz", "r:gz") as tar:
for file in tar.getmembers():
if file.isreg():
mov = file.name
proc = subprocess.Popen(tar.extractfile(file).read(), stdout = subprocess.PIPE)
proc2 = subprocess.Popen('bgzip -c > ' + clean(mov), stdin = proc, stdout = subprocess.PIPE)
mov = None
But now I get stuck on this:
Traceback (most recent call last):
File "preformat.py", line 12, in <module>
proc = subprocess.Popen(tar.extractfile(file).read(), stdout = subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 36] File name too long
Is there any workaround for this? I have been using the LightTableLinux.tar.gz (it contains the files for a text editor program) as a tarball to test the script on it.
The exception is raised in the forked-off child process when trying to execute the target program from this invocation:
proc = subprocess.Popen(tar.extractfile(file).read(), stdout = subprocess.PIPE)
This
reads the contents of an entry in the tar file
tries to execute a program with the name of the contents of that entry.
Also your second invocation won't work, as you are trying to use shell redirection without using shell=True in Popen():
proc2 = subprocess.Popen('bgzip -c > ' + clean(mov), stdin = proc, stdout = subprocess.PIPE)
The redirect may also not be necessary, as you should be able to simply redirect the output from bgzip to a file from python directly.
Edit: Unfortunately, despite extractfile() returning a file-like object, Popen() expects a real file (with a fileno). Hence, a little wrapping is required:
with tar.extractfile(file) as tarfile, file(clean(mov), 'wb') as outfile:
proc = subprocess.Popen(
('bgzip', '-c'),
stdin=subprocess.PIPE,
stdout=outfile,
)
shutil.copyfileobj(tarfile, proc.stdin)
proc.stdin.close()
proc.wait()