Sometimes it happens that you need to execute external command. Same happens when you are programming Erlang. Usually it is enough to use os:cmd. It executes the command and returns the result. Like the following
LsOut = os:cmd("ls"), % on unix platform
But sometimes you need to start the process and communicate with it via standard input and output. For example most of linux users know GnuChess program. And may be somebody even tried to start it from the shell without GUI. So, the following simple example will show how to start GnuChess and communicate with the process from Erlang.
-module(pipe).
-author('Sergiy Dzysyak ').
-compile(export_all).
start()->
spawn(?MODULE, read, []).
read() ->
Port = open_port({spawn,"/usr/bin/gnuchess -xe"},[binary,{line, 255}]),
do_read(Port).
do_read(Port) ->
receive
{Port,{data,Data}} ->
io:format("Data: ~p~n",[Data]);
{Port,eof} ->
read();
{go, Go} ->
Port ! {self(), {command, Go}};
Any ->
io:format("No match fifo_client:do_read/1, ~p~n",[Any])
end,
do_read(Port).
Example is very basic and to stat it you should do the following:
[serg@localhost erl.chess]$ erl
Erlang R14B03 (erts-5.8.4) [source] [64-bit] [rq:1] [async-threads:0] [kernel-poll:false]
Eshell V5.8.4 (abort with ^G)
1> c(pipe).
{ok,pipe}
2> Pid = pipe:start().
<0.38.0>
3> Pid ! {go, <<"e2e4\n">>}.
{go,<<"e2e4\n">>}
Data: {eol,<<"Chess">>}
Data: {eol,<<"Adjusting HashSize to 1024 slots">>}
Data: {eol,<<"1. e2e4">>}
Data: {eol,<<"1. ... e7e5">>}
Data: {eol,<<"My move is: e7e5">>}
4>
In a similar way communication via linux named pipes can be organized with external programs or even more complicated goals may be achieved. I have not tried to load drivers & communicate with them via port_open, but if I will get a minute, I will try and describe it here in my blog...