5
$\begingroup$

My question is if it is possible to directly open a (named) pipe using OpenRead.

Introduction

In the docs of OpenRead, we have, under details and options,

If OpenRead does not succeed in opening a particular file or pipe, it generates a message, and returns $Failed.

suggesting that we can open a pipe with OpenRead. However, we also have

On systems that support pipes, OpenRead["!command"] runs the external program specified by command, and opens a pipe to get input from it.

This last text adds to my suspicion that maybe it is only possible to open a stream indirectly. For example using something like OpenRead["!cat fifo"] (this may actually be a terrible command, but you maybe you get the gist. I.e. it seems that cat sometimes "terminates" and but mostly it doesn't, so that the kernel gets stuck waiting for the command to finish).

However, this answer by rcollyer quite explicitly does what I have failed to do. It reads a fifo using OpenRead.

My attempt

If I do (sorry about wasting your time with Pause, it is probably not necessary)

dir = FileNameJoin[{$TemporaryDirectory, "MMAIO"}];
CreateDirectory[dir]
Run["cd" <> " " <> dir <> " && mkfifo fifo"]
Pause[1]
OpenRead[FileNameJoin[{dir, "fifo"}]]

Then I simply get $Failed and a message that it cannot be opened. Also when I connect some input to the fifo or when I just append some string to the fifo, it wont work.

Questions

Am I doing something wrong or is this just impossible? Might it depend on the system? I am using Mac OSX and version 9. Also, is there any other way to get input from a pipe directly, or do we have to resort to something like OpenRead["!cat fifo"]?

Etc

This Q&A is related, but it is about MathematicaScript.

Background: The reason I bother with a fifo in the first place is to make a connection between Mathematica and other applications without writing on the hard disk. I am aware that MathLink might be something to look into.

$\endgroup$
  • $\begingroup$ Also: you can successfully write to a fifo using OpenWrite and Write/StringWrite. $\endgroup$ – Paul Jul 4 '13 at 21:39
  • $\begingroup$ You can avoid writing to a physical disk by creating a RAM Disk under OS X which can then be used in the normal way by both applications. tekrevue.com/tip/how-to-create-a-4gbs-ram-disk-in-mac-os-x $\endgroup$ – image_doctor Jul 5 '13 at 9:22
5
$\begingroup$

Use sockets. For example, set up a listening connection in shell with

nc -l 2222

Then in Mathematica

socket = SocketConnect["localhost:2222"]
str = ReadString[socket]

This will block unless there is data pending. Back in the shell where you ran "nc" type somethings and hit Ctrl-D. At this point ReadString should unblock and you should see the characters you entered into "nc" returned as Mathematica output. It is also possible to send data back with

WriteString[socket, str]

You can connect any application to Mathematica in this way by redirecting standard input and output through "nc" usnig two sockets

 nc -l 2222 | <your program> | nc localhost 3333

assuming Mathematica is listening on 3333.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.