isb
isb

Reputation: 53

How do I place output of bash command to Python variable?

How do I place output of bash command to Python variable?

I am writing a Python script, which I want to enter the output of bash command: rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} %{VENDOR}\n' | grep -v 'Red Hat'|wc -l, and place it to Python variable, let say R.

After that I want to do, Python if R != 0 then run some Linux command. How do I achieve that?

Upvotes: 2

Views: 721

Answers (4)

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

You can replace shell pipeline using Popen:

from subprocess import PIPE,Popen

p1 = Popen(["rpm", "-qa", "--qf", '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} %{VENDOR}\n'],stdout=PIPE)

p2 = Popen(["grep", "-v", 'Red Hat'],stdin=p1.stdout,stdout=PIPE)
p1.stdout.close()

p3 = Popen(["wc", "-l"],stdin=p2.stdout,stdout=PIPE)
p2.stdout.close()
out,err = p3.communicate()

If you just want to check if grep returned any matches then forget the wc - l and just check what grep returns:

p1 = Popen(["rpm", "-qa", "--qf", '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} %{VENDOR}\n'],stdout=PIPE)

p2 = Popen(["grep", "-v", 'Red Hat'],stdin=p1.stdout,stdout=PIPE)
p1.stdout.close()
out,err = p2.communicate()
if out:
   ...

Or just use check_output to run the rpm command and check the string for "Red Hat":

out = check_output(["rpm", "-qa", "--qf", '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} %{VENDOR}\n'])

if "Red Hat" not in out:
    ....

Which is the same as inverting the search with grep -v then checking if there are any matches with wc.

Upvotes: 0

Alex Ivanov
Alex Ivanov

Reputation: 823

You can use stdin.

#!/usr/bin/python

import  sys

s = sys.stdin.read()
print s

Then you will run a bash command like this

 echo "Hello" | ./myscript.py

Output

Hello

Upvotes: 0

ssundarraj
ssundarraj

Reputation: 820

I would recommend envoy primarily because the API is much more intuitive to use for 90% of the use cases.

r = envoy.run('ls ', data='data to pipe in', timeout=2)
print r.status_code  # returns status code
print r.std_out  # returns the output.

See the Envoy Github page for more details.

Upvotes: 0

Anthon
Anthon

Reputation: 76568

There are various options, but the easiest is probably using subprocess.check_output() with shell=True although this can be security hazard if you don't fully control what command is passed in.

import subprocess
var = subprocess.check_output('rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} %{VENDOR}\n' | grep -v 'Red Hat'|wc -l', shell = True)
var = int(var)

You need to use shell=True as otherwise the pipes would not be interpreted.

If you need more control you might want to look at plumbum where you can do:

from plumbum.cmd import rpm, grep, wc

chain = rpm["-qa", "--qf", r"%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} %{VENDOR}\n"] | grep["-v", "Red Hat"] | wc["-l"]
R = int(chain())

Although I would probably not invoke wc and get the whole output and count its length within python (easier to check that you got just the lines that you expected, piping through wc -l throws away all of the details)

Upvotes: 2

Related Questions