Tuesday, October 29, 2013

Pipe Input from stdin to an Erlang Program

Below is an Erlang program which read integers from the standard input and outputs them in reverse order. escript provides scripting support for short Erlang programs which can also take command line arguments.
#!/usr/bin/env escript

%hr.erl
r(L) ->
case io:fread("", "~d") of
eof ->
io:format("Reverse List: ~p~n", [L]),
ok;
{ok, [N]} ->
r([N|L])
end.

main(_) -> r([]).
I have inputs in a file in.txt.
4
5
6
0
1
2
To pass it the Erlang program we can use the pipe | operator with cat.
cat in.txt | escript hr.erl
This will produce the output
Reverse List: [2,1,0,6,5,4]
It is a normal practice to use the redirection operator < to send input as stdin taken from a file. But for some reasons, it's not working as intended with Erlang programs. The above program does not terminate if used with the redirection operator. It's the same case when using the command erl -noshell -s hr main < in.txt with exported module and function main/0. Of course, Erlang is not meant to be used like this. But still, it would be nice if we could. So finally pipe to the rescue. Instead of redirection, use pipe to send in input, which works correctly.