I'm trying to search a text file and retrieve lines containing a specific set of words. This is the code I'm using:
tyrs = subprocess.check_output('grep "^A" %s | grep TYR' % pocket_location, shell = True).split('\n')
This works fine when the file contains at least one line that grep identifies. But when grep doesn't identify any lines, grep returns exit status 1 and I get the following error:
Traceback (most recent call last):
File "../../Python_scripts/cbs_wrapper2.py", line 324, in <module>
tyrs = subprocess.check_output('grep "^ATOM" %s | grep TYR' % pocket_location, shell = True).split('\n')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 544, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command 'grep "^ATOM" cbsPrediction_files/1u9c_clean/1u9c_clean_fpocket_out/pockets/pocket0_atm.pdb | grep TYR' returned non-zero exit status 1
How can I avoid this issue? I just want subprocess.check_output
to return an empty string if grep doesn't find anything.
Thanks
The subprocess. check_output() is used to get the output of the calling program in python. It has 5 arguments; args, stdin, stderr, shell, universal_newlines. The args argument holds the commands that are to be passed as a string.
New in version 3.3. Subclass of SubprocessError , raised when a process run by check_call() , check_output() , or run() (with check=True ) returns a non-zero exit status. Exit status of the child process. If the process exited due to a signal, this will be the negative signal number.
subprocess. check_call() gets the final return value from the script, and 0 generally means "the script completed successfully".
To search a file employing grep in Python, import the “re” package, upload the file, and use a for loop to iterate over each line. On each iteration, use the re.search() method and the RegEx expression as the primary argument and the data line as the second.
I just want subprocess.check_output to return an empty string if grep doesn't find anything.
Well, too bad. grep
considers no matches to be failure, and the whole point of the check
in check_output
is to check for failure, so you're explicitly asking to do things this way. Here are the relevant docs:
If the return code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and any output in the output attribute.
And for grep
:
The following exit values shall be returned:
0 One or more lines were selected.
1 No lines were selected.
>1 An error occurred.
So, if you want to treat "no lines" as success, but actual errors as errors, you have to handle that 1
value differently than other non-zero values. And check_output
has no idea that you want to do that.
So, either you have to handle the CalledProcessError
, or you have to do your own checking. In other words, either this:
try:
tyrs = subprocess.check_output('grep "^A" %s | grep TYR' % pocket_location, shell = True).split('\n')
except subprocess.CalledProcessError as e:
if e.returncode > 1:
raise
tyrs = []
… or this:
p = subprocess.Popen('grep "^A" %s | grep TYR' % pocket_location, shell=True,
stdout=subprocess.PIPE)
output, _ = p.communicate()
if p.returncode == 1: # no matches found
tyrs = []
elif p.returncode == 0: # matches found
tyrs = output.split('\n')
else:
# error, do something with it
tyrs = subprocess.check_output('grep "^A" %s | grep TYR || true' % pocket_location, shell = True).split('\n')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With