So , i'm passing my parameters(a list and a string) to a perl file from my python file using subprocess , but it throws me a error.
The python code
import os
import subprocess
method = "operation"
data = ['param1', ' ', 'param2', 'LJs+p7l2KmzFWfhRxqAabcHWPHEGq2couwzktlfbpjwDoXb2GrWUGhrDwM3lwyFSK9R9rf6IAAE8szYVn3jBkQ==', ' ', ' ', 'filter_default', 'filter_default', 'filter_default',0,0]
proc = subprocess.Popen("perl"+" "+"file1.pl "+method+" " + " ".join([str(x) for x in data]),shell=True,stdout=subprocess.PIPE)
out,err = proc.communicate()
and while compiling it return's me this
illegal base64 data at input byte 6\n
Any quick fix for this?
There's nothing wrong with your base64 data. My guess is your Perl script is trying to decode "filter_default", where byte 6 IS invalid base64.
I notice you have spaces in your data list, but you are creating the command as one long string. That isn't going to be seen as blank parameters. You'll send
perl file1.pl operation param1 param2 lJs+p... filter_default filter_default
and the spaces won't be seen. If you really need to send empty parameters, then just send a list to Popen:
import os
import subprocess
method = "operation"
data = ['param1', ' ', 'param2', 'LJs+p7l2KmzFWfhRxqAabcHWPHEGq2couwzktlfbpjwDoXb2GrWUGhrDwM3lwyFSK9R9rf6IAAE8szYVn3jBkQ==', ' ', ' ', 'filter_default', 'filter_default', 'filter_default']
proc = subprocess.Popen( ["perl", "file1.pl", method] + data,shell=True,stdout=subprocess.PIPE)
out,err = proc.communicate()
Related
There is the following code, how to display all processes in it with one line and remove from each .exe?
import psutil
for proc in psutil.process_iter():
name = proc.name()
print(name)
to get it
chrome, opera, svhost, ...
To get them in one line, use sep parameter in print function:
import psutil
enlisted = [proc.name() for proc in psutil.process_iter()]
print(*enlisted, sep = ' ')
Or there is end parameter too.
import psutil
procs = [proc.name().replace('.exe', '') for proc in psutil.process_iter()]
print(', '.join(procs))
As mentioned by #Vicrobot, the print line could as well be replaced by
print(*procs, sep = ', ')
while keeping in mind that the default seperator of print is already ' '.
.
I want to execute a shell script with 3 arguments from a python script. (as described here: Python: executing shell script with arguments(variable), but argument is not read in shell script)
Here is my code:
subprocess.call('/root/bin/xen-limit %s %s %s' % (str(dom),str(result),str('--nosave'),), shell=True)
variables dom and result are containing strings.
And here is the output:
/bin/sh: --nosave: not found
UPDATE:
That is the variable "result":
c1 = ['/bin/cat', '/etc/xen/%s.cfg' % (str(dom))]
p1 = subprocess.Popen(c1, stdout=subprocess.PIPE)
c2 = ['grep', 'limited']
p2 = subprocess.Popen(c2, stdin=p1.stdout, stdout=subprocess.PIPE)
c3 = ['cut', '-d=', '-f2']
p3 = subprocess.Popen(c3, stdin=p2.stdout, stdout=subprocess.PIPE)
c4 = ['tr', '-d', '\"']
p4 = subprocess.Popen(c4, stdin=p3.stdout, stdout=subprocess.PIPE)
result = p4.stdout.read()
After that, the variable result is containing a number with mbit (for example 16mbit)
And dom is a string like "myserver"
from subprocess import Popen, STDOUT, PIPE
print('Executing: /root/bin/xen-limit ' + str(dom) + ' ' + str(result) + ' --nosave')
handle = Popen('/root/bin/xen-limit ' + str(dom) + ' ' + str(result) + ' --nosave', shell=True, stdout=PIPE, stderr=STDOUT, stdin=PIPE)
print(handle.stdout.read())
If this doesn't work i honestly don't know what would.
This is the most basic but yet error describing way of opening a 3:d party application or script while still giving you the debug you need.
Why not you save --nosave to a variable and pass the variable in subprocess
It's simpler (and safer) to pass a list consisting of the command name and its arguments.
subprocess.call(['/root/bin/xen-limit]',
str(dom),
str(result),
str('--nosave')
])
str('--nosave') is a no-op, as '--nosave' is already a string. The same may be true for dom and result as well.
I am using vb.net and Arcobjects for my program. I am creating a button for ArcMap 10 that will convert a kml to a lyr file.
I am having problems passing variables into the python code. The variables are file paths and it works great if I hard code them in with / instead of . When the variables are dynamically passed in, the program breaks at the "/"s in the path names:
Dim Filelocation As OpenFileDialog = New OpenFileDialog()
Filelocation.Title = "Please point photo of the owner"
Filelocation.InitialDirectory = "B:\GeoSpatialData\Projects\004402 Griffiths\File Structure\Geospatial\GPS\KML"
If Filelocation.ShowDialog = DialogResult.OK Then
Dim kmlFile As String
kmlFile = Filelocation.FileName
Dim args As String
args = kmlFile & " " & kmlFile.Substring(0, kmlFile.LastIndexOf("\")) & " test"
Dim args2 As String = args.Replace("\", "/")
Dim procStartInfo As System.Diagnostics.ProcessStartInfo = New System.Diagnostics.ProcessStartInfo("C:\Python26\python", "C:\Users\KJacobsen\kml_to_shp.py " & args2)
' The following commands are needed to redirect the standard output.
' This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = True
procStartInfo.UseShellExecute = False
' Do not create the black window.
procStartInfo.CreateNoWindow = False
' Now you create a process, assign its ProcessStartInfo, and start it.
Dim proc As New System.Diagnostics.Process()
proc.StartInfo = procStartInfo
proc.Start()
proc.WaitForExit()
' Get the output into a string.
Dim result As String = proc.StandardOutput.ReadToEnd()
' Display the command output.
Console.WriteLine(result)
End If
Catch objException As Exception
' Log the exception and errors.
Console.WriteLine(objException.Message)
End Try
My python script looks like this:
import os
import arcpy
import sys
import glob
arcpy.KMLToLayer_conversion(sys.argv[1],sys.argv[2],sys.argv[3])
print
The path returned contains spaces? It seems so from your initial directory.
In that case the command arguments passed to the script could be wrong.
Try to enclose everything in double quotes and avoid direct manipulation of paths.
Use Path.GetDirectoryName() instead
Dim args As String
args = """" + kmlFile + """ "
args = args & """" & Path.GetDirectoryName(kmlFile) & """ test"
Replace "\" to "\\\"
Does it work?
I have an application that takes input, either from the terminal directly or I can use a pipe to pass the output of another program into the stdin of this one. What I am trying to do is use python to generate the output so it's formatted correctly and pass that to the stdin of this program all from the same script. Here is the code:
#!/usr/bin/python
import os
import subprocess
import plistlib
import sys
def appScan():
os.system("system_profiler -xml SPApplicationsDataType > apps.xml")
appList = plistlib.readPlist("apps.xml")
sys.stdout.write( "Mac_App_List\n"
"Delimiters=\"^\"\n"
"string50 string50\n"
"Name^Version\n")
appDict = appList[0]['_items']
for x in appDict:
if 'version' in x:
print x['_name'] + "^" + x['version'] + "^"
else:
print x['_name'] + "^" + "no version found" + "^"
proc = subprocess.Popen(["/opt/altiris/notification/inventory/lib/helpers/aex- sendcustominv","-t","-"], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.communicate(input=appScan())
For some reason this subprocess I am calling doesn't like what is coming into stdin. However if I remove the subprocess items and just have the script print to stdout and then call the script from the terminal (python appScan.py | aex-sendcustominv), aex-sendcustominv is able to accept the input just fine. Is there any way to take a functions output in python and send it to the stdin of an subprocess?
The problem is that appScan() only prints to stdout; appScan() returns None, so proc.communicate(input=appScan()) is equivalent to proc.communicate(input=None). You need appScan to return a string.
Try this (not tested):
def appScan():
os.system("system_profiler -xml SPApplicationsDataType > apps.xml")
appList = plistlib.readPlist("apps.xml")
output_str = 'Delimiters="^"\nstring50 string50\nName^Version\n'
appDict = appList[0]['_items']
for x in appDict:
if 'version' in x:
output_str = output_str + x['_name'] + "^" + x['version'] + "^"
else:
output_str = output_str + x['_name'] + "^" + "no version found" + "^"
return output_str
proc = subprocess.Popen(["/opt/altiris/notification/inventory/lib/helpers/aex- sendcustominv","-t","-"], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.communicate(input=appScan())
I have a backup applications in python that needs to work on Windows. It needs UTF compatibility (to be able to backup directories that contain UTF characters like italian accents). The problem is it uses external programs (plink, cygwin, ssh and rsync) and I can't get them working. The prototype is 32 lines long, please take a look:
# -*- coding: utf-8 -*-
import subprocess
def safestr(obj, encoding='utf-8'):
r"""Converts any given object to utf-8 encoded string.
>>> safestr('hello')
'hello'
>>> safestr(u'\u1234')
'\xe1\x88\xb4'
>>> safestr(2)
'2'
"""
if isinstance(obj, unicode):
return obj.encode("utf-8")
elif isinstance(obj, str):
return obj.encode
else:
return str(obj)
def execute(command):
pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
out, errs = pipe.communicate()
retcode = pipe.poll()
print "OUT: " + repr(out)
print "ERRS: " + repr(errs)
print "RET: " + str(retcode)
command = u'rsync --stats -az --numeric-ids --delete --blocking-io --modify-window=2 --no-group --chmod=u=rwX,g=,o= -e \'cygnative plink -ssh -2 -batch -pw test \' "/cygdrive/c/κόσμε" vaidab#192.168.1.86:/volatile/backup/vaidab/2010-03-03.15_41_56/ --link-dest=../2010-03-03.15_00_57'.encode('utf-8')
execute(command)
Still doesn't work with nosklo's version, check the result:
python prototype_unicode_new.py
'rsync.exe --stats -az --numeric-ids --delete --blocking-io --modify-window=2 --
no-group --chmod=u=rwX,g=,o= -e "cygnative plink -ssh -2 -batch -pw test" /cygdr
ive/c/\xce\xba\xcf\x8c\xcf\x83\xce\xbc\xce\xb5 vaidab#192.168.1.86:/volatile/bac
kup/vaidab/2010-03-03.15_41_56/'
OUT: '\nNumber of files: 0\nNumber of files transferred: 0\nTotal file size: 0 b
ytes\nTotal transferred file size: 0 bytes\nLiteral data: 0 bytes\nMatched data:
0 bytes\nFile list size: 9\nFile list generation time: 0.001 seconds\nFile list
transfer time: 0.000 seconds\nTotal bytes sent: 22\nTotal bytes received: 12\n\
nsent 22 bytes received 12 bytes 68.00 bytes/sec\ntotal size is 0 speedup is
0.00\n'
ERRS: 'rsync: link_stat "/cygdrive/c/\xc3\x8e\xc2\xba\xc3\x8f\xc5\x92\xc3\x8f\xc
6\x92\xc3\x8e\xc2\xbc\xc3\x8e\xc2\xb5" failed: No such file or directory (2)\nrs
ync error: some files/attrs were not transferred (see previous errors) (code 23)
at /home/lapo/packaging/rsync-3.0.6-1/src/rsync-3.0.6/main.c(1039) [sender=3.0.
6]\n'
RET: 23
Don't use shell=True. EVER. It needlessy invokes a shell to call your program.
Pass the parameters as a list instead of a string.
This example should work, provided the parameters are right and the rsync.exe is in current folder (or PATH):
# -*- coding: utf-8 -*-
import subprocess
def execute(command):
pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, errs = pipe.communicate()
retcode = pipe.poll()
print "OUT: " + repr(out)
print "ERRS: " + repr(errs)
print "RET: " + str(retcode)
return out
command = ['rsync.exe', '--stats', '-az', '--numeric-ids', '--delete',
'--blocking-io', '--modify-window=2', '--no-group',
'--chmod=u=rwX,g=,o=', '-e',
'cygnative plink -ssh -2 -batch -pw test',
u'/cygdrive/c/κόσμε'.encode('utf-8'),
'vaidab#192.168.1.86:/volatile/backup/vaidab/2010-03-03.15_41_56/',
'--link-dest=../2010-03-03.15_00_57']
execute(command)
A piece of code that passeth all understanding:
if isinstance(obj, unicode):
return obj.encode("utf-8")
elif isinstance(obj, str):
return obj.encode
# the above is returning a METHOD ***************************
else:
return str(obj)
What's the point of doctests if you don't run them?