I am trying to get a domain name from a cpanel user in python.
Here is my code:
import subprocess
user = "testuser"
getuserdata = 'cat /var/cpanel/users/' + user
getdnsline = 'grep "DNS="'
test = 'wc -l'
userdataprocess = subprocess.Popen(getuserdata.split(), stdout=subprocess.PIPE)
testprocess = subprocess.Popen(test.split(), stdin=userdataprocess.stdout, stdout=subprocess.PIPE)
test, error = testprocess.communicate()
print(test)
dnslineprocess = subprocess.Popen(getdnsline.split(), stdin=userdataprocess.stdout, stdout=subprocess.PIPE)
website, error = dnslineprocess.communicate()
print(website.decode('utf-8').splitlines())
my output is:
b'60n'
[]
So this means, that the wc -l command gives back 60 lines. So passing the output of the first getuserdata command to the wc -l command works.
However, the grep command always return blank. No matter it I put in “DNS=” or “=” or even “a”. The file is the normal cpanel user file, and I have verified that DNS is in the file.
When I just output the data from the first process userdataprocess I can manually check for the DNS entry.
Do I have to do anything different when using the grep command in this fashion?
2
Answers
This is because your
testprocess.communicate()
for thewc -l
command already consumes all of the output ofuserdataprocess.stdout
and closes it in fact, so there’s nothing left fordnslineprocess.communicate()
to read.You should instead read the output of
userdataprocess.stdout
into a variable and then use it as an input to bothtestprocess.communicate()
anddnslineprocess.communicate()
.Also, as @pyb pointed out, you are unnecessarily quoting
DNS=
in yourgrep
command, which, without a shell, will be passed togrep
with double quotes included as part of the string to filter with. You should simply remove them as there are no special characters in your filter string.Your script fails because of the quotes around
DNS=
.You can use
shell=True
to make the script work:Source: Passing double quote shell commands in python to subprocess.Popen()?