[next][previous][up][top][index]
search for:

communicating with programs

The most naive way to interact with another program is simply to run it, let it communicate directly with the user, and wait for it to finish. This is done with the run command.

i1 : run "uname -a"
SunOS u00.math.uiuc.edu 5.7 Generic_106541-12 sun4u sparc

o1 = 0

More often, one wants to write Macaulay 2 code to obtain and manipulate the output from the other program. If the program requires no input data from us, as in the example above, then we can use get with a file name whose first character is an exclamation point; the rest of the file name will be taken as the command to run. In this example, we also peek at the string to see whether it includes a newline character.

i2 : peek get "!uname -a"

o2 = "SunOS u00.math.uiuc.edu 5.7 Generic_106541-12 sun4u sparc\n"

Bidirectional communication with a program is also possible. We use openInOut to create a file that serves as a bidirectional connection to a program. That file is called an input output file. In this example we open a connection to the unix utility egrep and use it to locate the symbol names in Macaulay2 that begin with in.

i3 : f = openInOut "!egrep '^in'"

o3 = !egrep '^in'

o3 : File
i4 : scan(keys symbolTable(), key -> f << key << endl)
i5 : f << closeOut

o5 = !egrep '^in'

o5 : File
i6 : get f

o6 = independentSets
     input
     index
     integrate
     indexComponents
     inducedMap
     infinity
     installMethod
     integralClosure
     inducesWellDefinedMap
     indices
     incomparable
     instance
     indeterminate
     intersect

With this form of bidirectional communication there is always a danger of blocking, because the buffers associated with the communication channels (pipes) typically hold only 4096 bytes. In this example we succeeded because the entire output from egrep was smaller than 4096 bytes. In general, one should be careful to arrange things so that the two programs take turns using the communication channel, so that when one is writing data, the other is reading it.

A useful function in this connection is isReady, which will tell you whether an input file has any input available for reading, or whether it has arrived at the end. We illustrate it in the following example by simulating a computation that takes 5 seconds to complete, printing one dot per second while waiting.

i7 : f = openIn "!sleep 5; echo -n the answer is 4"

o7 = !sleep 5; echo -n the answer is 4

o7 : File
i8 : isReady f

o8 = false
i9 : while not isReady f do (sleep 1; << "." << flush)
......
i10 : read f

o10 = the answer is 4
i11 : isReady f

o11 = true
i12 : atEndOfFile f

o12 = true
i13 : close f

o13 = !sleep 5; echo -n the answer is 4

o13 : File

We also allow for bidirectional communication through sockets over the internet. See openInOut and openListener, or the next section.

Another useful function is wait, which can be used to wait for input to be available from any of a list of input files.


[next][previous][up][top][index]
search for: