[erlang-questions] On Starting A Remote Shell Programmatically

Tim Watson <>
Sun Aug 22 20:29:30 CEST 2010

There is also an ssh application/module that wraps up the underlying details (like open_port). In terms of keeping track of nodes, there are a couple of things to consider. Firstly, if you're comfortable using distributed Erlang to keep track of the membership of your nodes then you can use net_kernel:monitor_nodes/2 to receive messages when they come up/down. There are some idiosyncrasies to watch out for with monitor_nodes/2, so you might find yourself fiddling around with erlang:start_timer/3 in conjunction with this approach. 

IMO you'd also be better looking at the slave module if you want to simplify managing these nodes. If you can't (or don't want to) rely on distributed Erlang for whatever reason, then you'll need a custom protocol. This is where something like riak_core would serve you very well. There are also some very useful modules in the scalaris codebase, although you'll need to copy (and comprehend) gen_component to do so. 


On 22 Aug 2010, at 17:46, 黃耀賢 (Yau-Hsien Huang) wrote:

> Thank you. Now I can use SSH to execute a remote command as
> "erl -rsh ssh -sname gandolf" , and eventually it sometimes show
> only the starting message of Erlang Shell and sometimes the starting
> message accompanied with the exit message. Then, How to write
> an Erlang program to robustly keep an alive remote shell?
> Related information is as following:
> % Commander
> test(Host, NodeName) ->
>    erlang:open_port({spawn,"ssh -f " ++ Host ++ " \"erl -rsh ssh -sname "
>                          ++ NodeName ++ "\" &",
>                 [{env,[{"PATH",os:getenv("PATH")}]}]),
>    receive
>        AnyThing -> io:format("Receive:" ~w~n.",[AnyThing]), AnyThing
>   after
>       5000 -> {error,no_response}
>   end.
> -----------------------------
> [ ~]$ erl -rsh ssh -sname me
> 1> c(test).
> {ok,test}
> 2> test:test("HPC9", "gandolf").
> Receive: {#Port<0.126>,{data,[69,115,... ]}}
> {#Port<0.126>,{data,"Eshell V5.6.1   (abort with ^G)\n"}}
> 3> net_adm:ping().
> pang
> Or,
> 2> {_,{S,D}} = test:test("HPC11", "mary"), io:format("~w:~s~n",[S,D]).
> Receive: {#Port<0.132>,{data,[69,115,... ]}}
> data:() 1> *** Terminating erlang ()
> ok
> 3>halt().
> 2010/8/22 Tim Watson <>
>> There is an ssh application distributed with OTP which should meet your
>> needs. It'll allow you to open an SSH connection and send commands over it,
>> so assuming you have installed the emulator on the remote machine, you
>> should be able to spin up another node. If you're planning on writing a
>> MapReduce framework, may I suggest that you look at riak_core (the
>> underpinning framework behind riak), and luke (
>> http://github.com/basho/luke) as these things have been done before. There
>> is also some excellent stuff in scalaris (
>> http://code.google.com/p/scalaris/) for coordinating work (paxos based
>> IIRC) and the disco project (http://discoproject.org/) has implemented a
>> MapReduce framework too, although jobs are written in python rather than
>> Erlang.

More information about the erlang-questions mailing list