run linux grep command from python subprocess - python

I know there are posts already on how to use subprocess in python to run linux commands but I just cant get the syntax correct for this one. please help. This is the command I need to run...
/sbin/ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'
Ok this is what I have at the moment that gives a syntax error...
import subprocess
self.ip = subprocess.Popen([/sbin/ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'])
Any help greatly appreciated.

This has been gone over many, many times before; but here is a simple pure Python replacement for the inefficient postprocessing.
from subprocess import Popen, PIPE
eth1 = subprocess.Popen(['/sbin/ifconfig', 'eth1'], stdout=PIPE)
out, err = eth1.communicate()
for line in out.split('\n'):
line = line.lstrip()
if line.startswith('inet addr:'):
ip = line.split()[1][5:]

Here's how to construct the pipe in Python (rather than reverting to Shell=True, which is more difficult to secure).
from subprocess import PIPE, Popen
# Do `which` to get correct paths
GREP_PATH = '/usr/bin/grep'
IFCONFIG_PATH = '/usr/bin/ifconfig'
AWK_PATH = '/usr/bin/awk'
awk2 = Popen([AWK_PATH, '{print $1}'], stdin=PIPE)
awk1 = Popen([AWK_PATH, '-F:', '{print $2}'], stdin=PIPE, stdout=awk2.stdin)
grep = Popen([GREP_PATH, 'inet addr'], stdin=PIPE, stdout=awk1.stdin)
ifconfig = Popen([IFCONFIG_PATH, 'eth1'], stdout=grep.stdin)
procs = [ifconfig, grep, awk1, awk2]
for proc in procs:
print(proc)
proc.wait()
It'd be better to do the string processing in Python using re. Do this to get the stdout of ifconfig.
from subprocess import check_output
stdout = check_output(['/usr/bin/ifconfig', 'eth1'])
print(stdout)

Related

| Not Working In Subprocess.call

Whenever I use a command in a subprocess with "|" in it doesn't work it has an output of
Command "|" is unknown, try "in link help".
Or when I put this:
#!/usr/bin/python
from subprocess import call
from shlex import split
interface = call(split("ip -o link show | awk '{print $2}' | grep wl"))
It is giving the output of:
Error: either "dev" is duplicate, or "awk" is a garbage.
You can use subprocess.check_output method and Popen class though I wasn't able to chain both pipe operations. Partial solution:
from subprocess import check_output, Popen, PIPE
from shlex import split
process = Popen(split('ip -o link show'), stdout=PIPE)
output = check_output(('awk', '{print $2}'), stdin=process.stdout)
return_code = process.wait()
print(output, return_code)
So basically, awk is taking the process standard output, and result is saved in the output variable.

How to run multi-line bash commands inside python?

I want to run the following lines of linux bash commands inside a python program.
tail /var/log/omxlog | stdbuf -o0 grep player_new | while read i
do
Values=$(omxd S | awk -F/ '{print $NF}')
x1="${Values}"
x7="${x1##*_}"
x8="${x7%.*}"
echo ${x8}
done
I know that for a single-line command, we can use the following syntax:
subprocess.call(['my','command'])
But, how can I use subprocess.call if there are several commands in multiple lines !?
quote https://mail.python.org/pipermail/tutor/2013-January/093474.html:
use subprocess.check_output(shell_command, shell=True)
import subprocess
cmd = '''
tail /var/log/omxlog | stdbuf -o0 grep player_new | while read i
do
Values=$(omxd S | awk -F/ '{print $NF}')
x1="${Values}"
x7="${x1##*_}"
x8="${x7%.*}"
echo ${x8}
done
'''
subprocess.check_output(cmd, shell=True)
I have try some other examples and it works.
Here is a pure python solution that I think does the same as your bash:
logname = '/var/log/omxlog'
with open(logname, 'rb') as f:
# not sure why you only want the last 10 lines, but here you go
lines = f.readlines()[-10:]
for line in lines:
if 'player_new' in line:
omxd = os.popen('omxd S').read()
after_ = omxd[line.rfind('_')+1:]
before_dot = after_[:after_.rfind('.')]
print(before_dot)

Python, evaluation output of OS command in an if statement

I want to convert the following shell evaluation to python2.6(can't upgrade). I can't figure out how to evaluate the output of the command.
Here's the shell version:
status=`$hastatus -sum |grep $hostname |grep Grp| awk '{print $6}'`
if [ $status != "ONLINE" ]; then
exit 1
fi
I tried os.popen and it returns ['ONLINE\n'].
value = os.popen("hastatus -sum |grep `hostname` |grep Grp| awk '{print $6}'".readlines()
print value
Try the subprocess module:
import subprocess
value = subprocess.call("hastatus -sum |grep `hostname` |grep Grp| awk '{print $6}'")
print(value)
Documentation is found here:
https://docs.python.org/2.6/library/subprocess.html?highlight=subprocess#module-subprocess
The recommended way is to use the subprocess module.
The following section of the documentation is instructive:
replacing shell pipeline
I report here for reference:
output=dmesg | grep hda
becomes:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
The p1.stdout.close() call after starting the p2 is important in order for p1 to receive a SIGPIPE if p2 exits before p1.
Alternatively, for trusted input, the shell’s own pipeline support may still be used directly:
output=dmesg | grep hda
becomes:
output=check_output("dmesg | grep hda", shell=True)
And here the recipe to translate os.popen to the subprocess module:
replacing os.popen()
So in your case you could do something like
import subprocess
output=check_output("hastatus -sum |grep `hostname` |grep Grp| awk '{print $6}'", shell=True)
or
concatenating the Popens as showed in the documentation above (probably what I would do).
Then to test the output you could just use, assuming you're using the first approach:
import sys
import subprocess
....
if 'ONLINE' in output:
sys.exit(1)

Error using shlex and subprocess [duplicate]

This question already has answers here:
How do I use subprocess.Popen to connect multiple processes by pipes?
(9 answers)
Closed 7 years ago.
Hi I am trying to run this command in python's subprocess with shlex split, however, I haven't found anything helpful for this particular case :
ifconfig | grep "inet " | grep -v 127.0.0.1 | grep -v 192.* | awk '{print $2}'
I get an with ifconfig error because the split with the single and double quotes and even the white space before the $ sign are not correct.
Please Help.
You can use shell=True (shell will interpret |) and triple quote string literal (otherwise you need to escape ", ' inside the string literal):
import subprocess
cmd = r"""ifconfig | grep "inet " | grep -v 127\.0\.0\.1 | grep -v 192\. | awk '{print $2}'"""
subprocess.call(cmd, shell=True)
or you can do it in harder way (Replacing shell pipeline from subprocess module documentation):
from subprocess import Popen, PIPE, call
p1 = Popen(['ifconfig'], stdout=PIPE)
p2 = Popen(['grep', 'inet '], stdin=p1.stdout, stdout=PIPE)
p3 = Popen(['grep', '-v', r'127\.0\.0\.1'], stdin=p2.stdout, stdout=PIPE)
p4 = Popen(['grep', '-v', r'192\.'], stdin=p3.stdout, stdout=PIPE)
call(['awk', '{print $2}'], stdin=p4.stdout)

How to run awk -F\' '{print $2}' inside subprocess.Popen in Python?

I need to run a shell command inside subprocess.Popen in Python.
The command is:
$ virsh dumpxml server1 | grep 'source file' | awk -F\' '{print $2}'
The output is:
/vms/onion.qcow2
I'm having two challenges with the above command:
1) The command is inside a loop, and where you see 'server1', it is a variable that will have a server name.
2) Python is complaining about KeyError: 'print $2'
Here is what I have so far:
proc = subprocess.Popen(["virsh dumpxml {0} | grep 'source file' | awk -F\' '{print $2}'".format(vm)], stdout=subprocess.PIPE, shell=True)
stdout = proc.communicate()[0]
Thanks in advance.
While it's possible use libvirt directly from python, your problem is that { is the format string, and surrounds print $2 in your awk script as well, so you have to escape those braces like
proc = subprocess.Popen(["virsh dumpxml {0} | grep 'source file' | awk -F\\' '{{print $2}}'".format(vm)], stdout=subprocess.PIPE, shell=True)
stdout = proc.communicate()[0]

Categories

Resources