Search code examples
pythonpython-3.xsubprocesspopen

Resource unavailable when piping subprocess


I am trying to find the path to the MATLAB executable using Python when it is not in PATH. I am using subprocess.Popen to execute locate and grepping the result, however this creates a Resource Unavailable error:

locate = subprocess.Popen(['locate', 'matlab'], stdout=subprocess.PIPE)
grep = subprocess.Popen(['grep', '/bin/matlab$'], stdin=locate.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result, err = grep.communicate()
MATLAB_PATH = result.decode('UTF-8').split()

The result variable is empty and err variable is :

b'grep: (standard input): Resource temporarily unavailable\n'

Solution

  • I have tried your code on linux with python 3.5.2 and 3.6.1 and it does work:

    locate = subprocess.Popen(['locate', 'find'], stdout=subprocess.PIPE)
    grep = subprocess.Popen(['grep', '/bin/find$'], stdin=locate.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    grep.communicate()
    (b'/usr/bin/find\n', b'')
    

    For the records: locate find gives 1619 lines. For completeness I have also tried locate fdafad (gibberish) and it also works.

    It does also work when the code is in a script.

    edit:

    Try to use communicate to interact between to two processess:

    locate = subprocess.Popen(['locate', 'find'], stdout=subprocess.PIPE)
    stdout, stderr = locate.communicate()
    grep = subprocess.Popen(['grep', '/bin/find$'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(grep.communicate(input=stdout))
    

    NOTE: the second part of the answer has been written before the asker updated the question with information about the PATH

    However there is a much better ways to find executables using python:

    from distutils.spawn import find_executable
    find_executable('find')
    
    '/usr/bin/find'
    

    If you insist in using shell functions, why don't use something like which.