argument_list = ['name=Jon', 'id=100' ]
output = subprocess.check_output(
['/usr/bin/python', 'test.py', argument_list ], stderr=subprocess.STDOUT)
In simple terms, I am trying to invoke a script using subprocess called test.py; I want to pass arguments to test.py through a list. Importatnt - List can be of any size.
Things I tried ,
output = subprocess.check_output(
['/usr/bin/python', 'test.py', ", ".join(argument_list) ], stderr=subprocess.STDOUT)
and
output = subprocess.check_output(
['/usr/bin/python', 'test.py', '%s' % argument_list ], stderr=subprocess.STDOUT)
Neither works because in subprocess.checkoutput should be (' ', ' ' ,' ') etc....
Is there a better way to do this ?
You can make a new list by adding lists together:
output = subprocess.check_output(['/usr/bin/python', 'test.py'] + argument_list, stderr=subprocess.STDOUT)
This will run test.py with argument_list as it's command-line parameters.
Related
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()
I'm trying to pass a parameter that enables verbose logging with syslog. Passing -v to the application definitely works as expected. So I am trying to add this option to a json config file.
Here is what I have in the json config:
"rtl": {
"freq": 144.390,
"ppm": -3,
"gain": 44.5,
"debug": true,
"offset_tuning": false,
"device_index": 0,
},
Here is what I have in the code. Note: All the other parts work except when I add the -v statement.
if self.config['source'] == 'rtl':
proc_src = subprocess.Popen(
['rtl_fm', '-f', str(int(self.config['rtl']['freq'] * 1e6)), '-s', '22050',
'-v', str(self.config['rtl'].get('debug', 'true')), '-v'],,
'-p', str(self.config['rtl']['ppm']), '-g', str(self.config['rtl']['gain']),
'-E', 'offset' if self.config['rtl'].get('offset_tuning', False) else 'none',
'-d', str(self.config['rtl'].get('device_index', 0)), '-'],
stdout=subprocess.PIPE, stderr=open('/dev/null')
)
Here is the error I get:
SyntaxError: ('invalid syntax', ('/usr/local/lib/python2.7/dist-packages/pymultimonaprs/multimon.py', 37, 62, "\t\t\t\t\t'-v', str(self.config['rtl'].get('debug', 'true')), '-v'],\n"))
It seems like tabs are getting thrown into the -d statement. I'm fairly new to python and just struggling with this. Any ideas?
Two commas:
'-v', str(self.config['rtl'].get('debug', 'true')), '-v'],,
^^
proc_src = subprocess.Popen(
['rtl_fm',
'-f', str(int(self.config['rtl']['freq'] * 1e6)),
'-s', '22050',
'-v', str(self.config['rtl'].get('debug', 'true')),
'-v', #?
'-p', str(self.config['rtl']['ppm']),
'-g', str(self.config['rtl']['gain']),
'-E', 'offset'
if self.config['rtl'].get('offset_tuning', False) else 'none',
'-d', str(self.config['rtl'].get('device_index', 0)), '-'
],
stdout=subprocess.PIPE, stderr=open('/dev/null'))
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.
save = "/root/foo/"
PERF_PATH="/root/foobar/"
So, Initially I had the variable save and perf_path in the cmd. but now, I want to substitute it for enhanced readability.
I wanted to create a folder into which the variable app[a] will eventually get stored.
direc = os.mkdir(save + i + "-"+ j +"-" + k + "-" +l)
Creating a directory does not seem to a problem.
but joining a non-string value variable to a string seems to be a problem.
cmd = "taskset -c %s" + PERF_PATH + "perf2 stat -t %s e r4008387e1 -f -o" +save + direc + "%s.csv &" % (cpus_list[a],fpid[a],apps[a])
pro= subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE, preexec_fn=os.setsid)
TypeError: cannot concatenate 'str' and 'NoneType' objects
cmd = "taskset -c %s" + str(PERF_PATH) + "perf2 stat -t %s e r4008387e1 -f -o" +str(save) + str(direc) + "%s.csv &" % (cpus_list[a],fpid[a],apps[a])
that wasn't of much help either.
any ideas how I can solve this?
os.mkdir() does not return anything, so direc is set to None.
Do this instead:
direc = save + i + "-"+ j +"-" + k + "-" +l
os.mkdir(direc)
You really want to use os.path.join() and string formatting to build paths though, it'll be a lot easier to read:
save = "/root/foo"
PERF_PATH="/root/foobar"
direc = os.path.join(save, '-'.join((i, j, k, l)))
os.mkdir(direc)
For subprocess.Popen(), pass in a list instead of a string for the command and arguments, and leave shell to the default value of False, there is no need to have the shell handle that:
cmd = ['taskset',
'-c', cpus_list[a], PERF_PATH, 'perf2', 'stat',
'-t', fpid[a], 'e', 'r4008387e1',
'-f', '-o', save,
os.path.join(direc, "%s.csv" % apps[a])
]
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, preexec_fn=os.setsid)
os.mkdir returns None.
Trying to add a string to a None is a no no. If you want to build up a string out of different types try using format:
s = 'hi there number {no}'.format(no=81)
This way is much more readable, thus debuggable, anyway
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())