How to get only one specific line from subprocess output - python

I know how to search if specific word exists in subprocess output. But how can I print out only one specific line, if I know this line always looks like:
This is the line: some text
"Some text" can have different values.
What I have:
variable = subprocess.call(["some", "command"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = output.communicate()
What I want to get after executing the script:
This is the line: some text

import subprocess
p = subprocess.Popen(["some", "command"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
stdout=stdout.split("\n")
for line in stdout:
if line.startswith("This is the line:"):
print line

Related

How to run a non ending process via subprocess and collect both STDOUT and STDERR separately

I have a python program which executes subprocess.Popen, like this;
process = subprocess.Popen(stand_alone_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = process.communicate()
print "out: ", out
print "err: ", err
If my stand_alone_command will run forever, how do I get whatever stand_alone_command is throwing at STDOUT and STDERR so that I can log it.
Try reading from stdout instead of calling communicate() such as..
import subprocess
sac = ['tail', '-f', '/var/log/syslog']
process = subprocess.Popen(sac, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while 1:
line = process.stdout.readline()
if line:
print(line)
I think you'll need to set shell=False but I'm on Linux and Windows is a bit different.

subprocess cmd is returning null (Python)

Trying to write a script that checks a directory for files which then uses the names of the files found to insert in to a subprocess command as shown below:
for filename in os.listdir('/home/dross/python/scripts/var/running/'):
print(str(filename))
cmd = 'app_query --username=dross --password=/home/dross/dross.txt "select row where label = \'Id: ' + filename + '\' SHOW status"'
print(cmd)
query = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
query.wait()
If I run the command manually from the command line there are 2 possible values returned "Error:No result" or "True"
When the "Error: No result" condition is true the script returns the same however when the "True" condition is present nothing is returned.
If the result of the print statement is copied and pasted in to the os command line it runs and returns "True"
What could be the deception I am seeing here ?
Is there a better approach to achieve what I am trying to do ?
You seem to be missing a call to .communicate(), to read the results of the command through the pipe.
In your original query = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) then anything send to stderr will be displayed on the screen, which seems to be what's happening for your error message. Anything sent to stdout will be sent to the pipe, ready for reading with communicate()
Some experimenting, showing that you won't see what's written to the subprocess.PIPE channels unless you communicate with the command you've run, and that stderr will display to the terminal if it's not redirected:
>>> import subprocess
>>> query = subprocess.Popen('echo STDERR 1>&2', shell=True, stdout=subprocess.PIPE)
STDERR
>>> query.wait()
0
>>> print(query.communicate())
('', None)
>>> query = subprocess.Popen('echo STDERR 1>&2', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> query.wait()
0
>>> print(query.communicate())
('', 'STDERR\n')
>>> query = subprocess.Popen('echo STDOUT', shell=True, stdout=subprocess.PIPE)
>>> query.wait()
0
>>> print(query.communicate())
('STDOUT\n', None)
So, to use your code from the question, you want something like this:
for filename in os.listdir('/home/dross/python/scripts/var/running/'):
print(filename) # print can convert to a string, no need for str()
cmd = 'app_query --username=dross --password=/home/dross/dross.txt "select row where label = \'Id: ' + filename + '\' SHOW status"'
print(cmd)
query = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
query.wait()
output, error = query.communicate()
print("stdout: {}".format(output))
print("stderr: {}".format(error))

subprocess call on python gives Error "Bad file descriptor"

Whenever i call a c code executable from Python using the method below I get a "Bad file descriptor" error. When I run the code from the command prompt it works fine. Help please!?
import subprocess
p = subprocess.call(['C:\Working\Python\celp.exe', '-o', 'ofile'], stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
In [84]: %run "C:\Working\Python\test.py"
Error: : Bad file descriptor
You forgot to add the stdout flag. add stdout = subprocess.PIPE, like this:
p = subprocess.call(
['C:\Working\Python\celp.exe', '-o', 'ofile'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, # needed for the next line to be sensible
stderr=subprocess.STDOUT,
)
now, try run your script again
Try this
import subprocess
p = subprocess.call(['C:\Working\Python\celp.exe', '-o', 'ofile'], stdin=subprocess.PIPE, stderr=subprocess.STDOUT, shell = True)

Python create text file without newline intepretation

I'm starting with python and i'm creating a script who will run valgrind and all the binairies in the folder, catch the output and create text file if the result need to be checked. My problem is that i get the output but when i print it or write it into a new file, \n charactere are not interpreted and display like two charactere, not as a newline that they should.
how I catch the output
proc.append(subprocess.Popen(
['valgrind','--track-origins=yes','--leak-check=full',''.join(['./',files[i]])],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
shell=False,
))
print '--> valgrind on', files[i]
stdout_value.append(proc[j].communicate())
how I write it in a new file
file = open(''.join([os.getcwd(),'/valgrind_output_dir/',result4.group(1),'_output.txt']), "w")
file.write(str(stdout_value[i]))
Thanks to tell me what I am doing wrong!
Try this one:
import subprocess
with open("file", "wb") as new_file:
proc = []
proc.append(subprocess.Popen(
["ls", "-l"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
shell=False,
))
new_file.write(proc[0].communicate()[0])
Problem may be: proc[0].communicate() => (TEXT, NONE)
Popen.communicate(input=None)
Interact with process: Send data to
stdin. Read data from stdout and stderr, until end-of-file is reached.
Wait for process to terminate. The optional input argument should be a
string to be sent to the child process, or None, if no data should be
sent to the child.
communicate() returns a tuple (stdoutdata, stderrdata).

Manipulating python stdout/stderr using subprocess

I am trying to manipulate/strip the output of 7zip command and intimate user about the progress of process. The sample code i am trying to use is below:
import subprocess
proc = subprocess.Popen(['7zip','arg', 'archive'],shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
line = proc.stdout.readline()
if line != '':
#Do some striping and update pyqt label
print "test:", line.rstrip()
sys.stdout.flush()
else:
break
However, the real problem is that print statement only print stdout after completion of the process. Is there a way to capture the stdout line by line then manipulate and print again?
Update
Updated the script to include sys.stdout.flush()
Yes, the popen family of calls.
You can see the documentation here
(child_stdin,
child_stdout,
child_stderr) = os.popen3("cmd", mode, bufsize)
==>
p = Popen("cmd", shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
child_stdout,
child_stderr) = (p.stdin, p.stdout, p.stderr)
they give you filedescriptors to the streams and you can use them to read the output of the called program.

Categories