python + run system command with variables - python

I need to run system command from python
I have python - version - Python 2.4.3
I try the following , in this example ls -ltr | grep Aug
#!/usr/bin/python
import commands
Month = "Aug"
status,output = commands.getstatusoutput(" ls -ltr | grep Month " )
print output
how to insert the Month variable in the command ?
so grep will do that
| grep Aug
I try this also
status,output = commands.getstatusoutput( " ls -ltr | grep {} ".format(Month) )
but I get the following error
Traceback (most recent call last):
File "./stamm.py", line 14, in ?
status,output = commands.getstatusoutput( " ls -ltr | grep {} ".format(Month) )
AttributeError: 'str' object has no attribute 'format'

import commands
Month = "Aug"
status,output = commands.getstatusoutput(" ls -ltr | grep '" + Month + "'")
print output
Or a couple other possibilites are:
status,output = commands.getstatusoutput("ls -ltr | grep '%s'" % Month)
or
status,output = commands.getstatusoutput(" ls -ltr | grep \"" + Month + "\"")

You don't need to run the shell, there is subprocess module in Python 2.4:
#!/usr/bin/env python
from subprocess import Popen, PIPE
Month = "Aug"
grep = Popen(['grep', Month], stdin=PIPE, stdout=PIPE)
ls = Popen(['ls', '-ltr'], stdout=grep.stdin)
output = grep.communicate()[0]
statuses = [ls.wait(), grep.returncode]
See How do I use subprocess.Popen to connect multiple processes by pipes?
Note: you could implement it in pure Python:
#!/usr/bin/env python
import os
from datetime import datetime
def month(filename):
return datetime.fromtimestamp(os.path.getmtime(filename)).month
Aug = 8
files = [f for f in os.listdir('.') if month(f) == Aug]
print(files)
See also, How do you get a directory listing sorted by creation date in python?

Related

How to port python2 code to python3?

I find out the following code that print shellcode or machine code of the objdump in the output but in python3 i can't run it. How can I port it to python3:
import subprocess
import sys
from subprocess import Popen
num_of_args = len(sys.argv)
binary_file = sys.argv[1]
#| awk -F'[:]' '{print $2}' | awk -F'[ ]' '{print $1}' | tr -d '[[:space:]]'
proc = subprocess.Popen(['arm-linux-gnueabi-objdump','-d',binary_file], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
line = proc.stdout.readline()
if line != '':
array = line.rstrip().split(':')
if len(array) > 1:
if array[1]:
array2 = array[1].split(' ')
array2 = array2[0].lstrip().rstrip()
if array2:
sc_part = '"'
sc_part += '\\x'
sc_part += '\\x'.join(a+b for a,b in zip(array2[::2], array2[1::2]))
sc_part += '"'
print sc_part
else:
break
Use the 2to3 tool that comes bundled with the python distribution. An example of its usage is this:
foo.py
def foo:
for i in xrange(5):
print i,
foo()
In the command line, you'll type:
$ 2to3 -w foo.py
foo.py (post command):
def foo():
for i in range(5):
print(i, end=' ')
foo()
Running 2to3 on your code, it appears only the print needs changing: print(sc_part)
print(sc_part) may well be the only thing you need to change.
It would be helpful if you pasted the stacktrace.
Anyways, try replacing print sc_part with print(sc_part)
Furthermore, you can read all of the changes in Python3 here.

Getting Python to print to the command line (the output of the graphviz command gvpr)

I'm trying to get Python to run this command, which runs fine from my command prompt:
ccomps -x rel_graph.dot | gvpr -c "N[nNodes($G)<5]{delete(0,$)}" | dot | gvpack | sfdp -Goverlap=prism | gvmap -e | gvpr "BEGIN{int m,w,e = 0} N[fontcolor=='blue']{m += 1} N[fontcolor=='green']{e += 1} N[fontcolor=='red']{w += 1} END{print(m); print(w); print(e);}"
In Python, I'm using:
temp = subprocess.Popen("""ccomps -x rel_graph.dot | gvpr -c \
"N[nNodes($G)<5]{delete(0,$)}" | dot | gvpack | sfdp -Goverlap=prism \
| gvmap -e | gvpr 'BEGIN{int m,w,e = 0} \
N[fontcolor=="blue"]{m += 1} \
N[fontcolor=="green"]{e += 1} \
N[fontcolor=="red"]{w += 1} \
END{print(m); print(w); print(e);}'
""", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
...and then read/print lines from temp. The issue is that Python doesn't print the three last print statements (all are integers) to standard output, or at least I wasn't able to find it. The rest of the gvpr program works fine from Python.
Thanks!
After some more work I changed the BEGIN quotation marks to double, and all the internal arguments to single, and that seems to have solved the issue.
You can send the stdout \ stderr to files likes this -
from subprocess import Popen
std_out_file = "/tmp/stdout.log"
std_err_file = "/tmp/stderr.log"
command_to_execute = "<your-command>"
with open(std_out_file, "wb") as out, open(std_err_file, "wb") as err:
p = Popen(command_to_execute, shell=True, cwd=<folder>, stdout=out, stderr=err)
p.communicate()
Then you read the stdout \ stderr from the files, for example:
f = open(std_out_file, "r")
stdout = f.readlines()
f.close()
You can check the return code of the command, to check if you also need to print the stderr like this -
if p.returncode == 0:

python function returning "22, 'Invalid argument'" when calling from jenkins framework

I am using jenkins framework to run python script in unix shell but its giving error like :
CRITICAL - (22, 'Invalid argument')
Same script works fine when execute manually from shell.
Here is my code:
FUNCTION 1:
def check_diskspace(ip,usr):
l = []
cmds='ssh %s#%s'%(usr,ip)
child1=pexpect.spawn(cmds)
for i in range(1,5):
child1.sendline("df -h /d/oss/global | awk '{if (NR>2) {print}}' | awk -F ' ' '{print $" + str(i) + "}'")
child1.expect(prompt)
l.append(child1.before.strip(cmds).split('\n')[1])
return l
FUNCTION 2
def TC1():
logger.info("Start TC1")
l = check_diskspace(nfsip,username)
Totalspace = l[0].strip('\r')
print "Totalspace=",Totalspace
if('global_100fill' == sys.argv[1]):
TC1()
Note: I am calling script from jenkins as:
/usr/local/bin/python2.7 /var/lib/jenkins/workspace/Stress_test/Stress_framework/usecase.py global_100fill

Pipe character is messing up my pexpect command string

I have a string that I build then pass to pexpect:
command = "for i in `python /tmp/"+ cecUser + "_getSyslogs.py " + startString + " " + endString + " " + myDir + "`;do gzcat /emslogs/archive/" + myDir + "/$i | grep " + node + " | egrep -v \"" + filteredWords + "\" >> /tmp/" + syslogFile + ";done"
p.sendline(command)
If filteredWords = "No LMA address", the script runs fine.
If filteredWords = "No LMA address|CLISess", the script fails.
What am I missing? I tried to escape the | by preceding with \ and that didn't help. I actually tried a whole slew of different combinations and the script still fails. What is even odder is the logging output from p.logfile looks fine:
$ for i in `python /tmp/getSyslogs.py 20141227120000 20141228120000 local1`;do gzcat /emslogs/archive/local1/$i | grep ALPRGAGQPN2 | egrep -v "No LMA address|CLISess" >> /tmp/1419900585.83_ALPRGAGQPN2_syslogs.txt;done
If I cut'n'paste that line on the target machine, it works no problem. There is just something about the pipe in the egrep that is messing up when passed to p.sendline.

How to use list data as variable

I need to use list value as variable. How could it be done.
comp_list = [ "list1", " list2", "list3"]
for comp in comp_list:
print (comp)
cmd = 'ps -aef | grep $comp'<<<<
print (cmd)
status, command = getstatusoutput(cmd)
the <<< directing to $comp should be replaced by list1 and then list2 and it should go on.
cmd = 'ps -aef | grep $comp'<<<<
This could be done like this:
cmd = 'ps -aef | grep %s' % comp
You could either use str.format:
cmd = 'ps -aef | grep {}'.format(comp)
Or just concatenate strings:
cmd = 'ps -aef | grep ' + comp

Categories

Resources