Search code examples
python-2.7named-pipesfifoattributeerror

Using os.open() and .read() on a named pipe in python2.7 results in AttributeError


I'm using Python2.7 and my operating system is Ubuntu14.04.

In my python code I'm using fifo = os.open('fifo', os.O_NONBLOCK | os.O_RDONLY) to open a named pipe. I then use string = fifo.read(7) to read seven characters from that pipe. Before running the code I create the pipe in the command line with mkfifo fifo. When I try to run the code I get the following error:

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    string = fifo.read(7)
AttributeError: 'int' object has no attribute 'read'

Why is this happening and how can I fix it?

More details if needed:
I'm using the fifo to pipe the output of an answer-set-programming (ASP) file into a string in my python code. The python file's output is being piped to the input of the ASP file (running in query mode). So, python sends a query to ASP, response is put into the fifo pipe, python reads that response into a string.

The reason I'm using O_NONBLOCK is that execution was stalling without it, though I don't know why as I'm pretty sure the ASP file was writing to the fifo; I tested a similar method using a text file instead of a fifo, and the ASP output was definitely going into the text file.

I'm running my code with the command python pythonfile.py | java -jar sparc.jar aspfile.sp > fifo.

Please notify me in a comment if you need more information and I will post my code. Thank you for any advice you can provide.


Solution

  • os.open corresponds to the underlying C library's open(3) call. It returns a file descriptor which is just an integer index (corresponding C type is int).

    To use the file descriptor, just use os.write/os.read, or wrap it in a file object by os.fdopen. You cannot call the read method on it, because a file descriptor is just a Python integer and there's no read method on an integer.

    References: Python library reference for os, and Unix C man pages in section 3.

    P.S. To create a named pipe, just use os.mkfifo. No need to fork an external command. The os module wraps most of the POSIX I/O functions.