简体   繁体   中英

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 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?

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)

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM