How to run Erlang nodes? - erlang

How to create new node? i try some like here
how to run this erlang example
and find the same in tutorial
http://www.erlang.org/doc/reference_manual/distributed.html when i write
% erl -name dilbert
my compiler behaves i forgot '.' at the end. Of course i try end, result the same.
Any ideas?

The command erl -name dilbert is not meant to be typed into the Erlang shell; it's the command you run to start a distributed node instead of plain erl.
(If you really want to turn a running node into a distributed node, you can use net_kernel:start/1, but I've never had a reason to do that except in tests.)

In Linux, you can type erl -name dilbert in the terminal.
In Windows you run it in CMD.

Related

Erlang Erl commands not working on Windows 10

Hello i was trying to issue some distributed erlang commands such as erl -sname/erl -name and i do not get a response.
If i put . at the end it says syntax error.
If i don't it won't return anything and it will treat it like an unfinished command.
I thought this is only for these commands but it seems there are others that will not do anything like
erl -man <module_name>.
Do i need to set something up to be able to issue erl commands.
P.S OS is Windows 10.
The erl command (with or without -sname) is simply how you run Erlang from a console window like cmd or powershell. On Windows, to get a fully working Erlang shell with command line editing etc, you need to use the special werl executable instead of erl - this is due to how Windows consoles work. Try opening a cmd or powershell windows and see how it works.
If you open the properties of the icon you have used for starting Erlang, you will see that the command it is running is werl (from the Start menu you have to use "more -> open file path" to find the actual icon first). You can edit this and add options like -sname yournodename to the command, or you can create a copy of the icon (e.g. to your desktop) and give it a more suitable name, like "My Erlang node", and then edit its options.

Erlang heartbeats

I am trying to create an application that can run on two different machines on the same network, and when one of the applications crahes, I want to use erlang heartbeat system to make it restart. How can I do this?
I've read the documentation, but have not figured out how to achieve this in practice.
Thanks
Did you specifically read http://erlang.org/doc/man/heart.html and try to follow the instructions there? In particular, you have to first set the environment variable HEART_COMMAND to the full command line to be used to restart your system.
To make this easier, you could use a launch script like this:
#!/bin/sh
erl -detached -heart -env HEART_COMMAND "$0 $#" -env HEART_BEAT_TIMEOUT 20 -sname mynode
In some environments (such as embedded systems) you might prefer a full OS reboot, and could simply run something like this:
#!/bin/sh
erl -detached -heart -env HEART_COMMAND "reboot" -env HEART_BEAT_TIMEOUT 20 -sname mynode

client on one node server on other node but on same host in erlang language

Here is the code iam confused when i was executing in Erlang shell so please explain me
In first terminal we set the terminal name as gandalf
erl -sname gandalf
(gandalf#localhost) 1> kvs:start().
In second terminal terminal name is bilbo
erl -sname bilbo
(bilbo#localhost) 1> rpc:call(gandalf#localhost, kvs,store, [weather, fine]).
But the problem is when i was executing the above code in respective terminals code was not getting executed so please explain me and i have one more doubt is it compulsory to set cookies??
Do you connect node before rpc:call?

to_erl program output

When I try to connect to an Erlang shell using the following command:
to_erl /tmp/erlang.pipe.1
The output of the command is something like this:
Attaching to /tmp/erlang.pipe.1 (^D to exit)
(search)`':
(node#mypc)1>
What is that "(search)`':"?
I use the following command to start the Erlang node to attach to:
run_erl -daemon /tmp/ /tmp "erl -sname node"
I think it is the shell search history mentioned in item OTP-10739 here. I think this should be considered a bug and be reported as such to the erlang-patches mailinglist.

How to run Erlang from unix shell with complex params?

I need to run complex Erlang module function from unix shell
rpc:call('node#example.com', mnesia, dirty_first, [mytable])
how can i do it?
UPD:
i make test.escript
chmod +x test.escript
#!/usr/lib64/erlang/bin/escript
%%! -name 'test#example.com'
main(_Args) ->
R = rpc:call('node#example.com', mnesia, dirty_first, [mytable]),
io:format("~p~n",[R]).
and receive {badrpc, nodedown}
but when run
erl -name test#example.com
1> rpc:call('node#example.com', mnesia, dirty_first, [mytable]).
{my, data}.
I mean it works, but howto make escript work proprely?
I think escript might be something worth looking into.
Edit:
Some examples.
First for all examples: Start the remote node somewhere, somehow.
dannib#duval:~:> erl -sname bar
(bar#duval)1> erlang:get_cookie().
'KNKKCFPYMJUPIOLYPOAA'
Escript
1: Create a file named hello.escript with content
#!/usr/bin/env escript
%%! -sname foo#duval -setcookie KNKKCFPYMJUPIOLYPOAA
main(_String) ->
Node = 'bar#duval',
Mod = 'erlang',
Fun = 'node',
Args = [],
R = rpc:call(Node, Mod, Fun, Args),
io:format("Hello there ~p~n",[R]).
Notice that the %%! -sname foo#bar identifies the node on the host (instead of creating nonode#nohost), allow setting the same cookie %%! -sname foo#duvel -setcookie KNKKCFPYMJUPIOLYPOAA as target host which solves the problem of getting {badrpc,nodedown}. Notice that the same statement holds for the following examples (erl_call, and -eval) where both the node name and cookie is set.
2: Set the execution bit and run
$ chmod +x hello.escript
$ ./hello.escript
Hello there bar#duval
Erl_call
1: run
$ erl_call -c 'KNKKCFPYMJUPIOLYPOAA' -a 'erlang node' -n bar#duval
bar#duval
Eval
1: run
$ erl -sname foo -setcookie 'KNKKCFPYMJUPIOLYPOAA'
-eval 'io:format("Hello there ~p~n",[rpc:call(bar#duval,erlang, node, [])])'
... Eshell V5.7.4 (abort with ^G)
(foo#duval)1> Hello there bar#duval
This creates a shell which might not be what you want in this case.
I might mention that if both nodes are on the same host and using the same cookie default value, the cookie value for foo and bar don't have to be explicitly set like in the examples.
After doing these examples and reading your question again I think what I GIVE TERRIBLE ADVICE said will be your best choice, erl_call. I fell for the word "complex" in question title where imho escripts allow much more "complex" setups in a easy-to-read manner. The variable _String in the escript example holds the arguments to the script which allows you to both access input through shell and perform complex erlang operations in the EVM. But erl_call might be more straight forward if you already have logic in some other application and just need to make this simple call to an erlang node.
The erl_call application is exactly what you need:
erl_call makes it possible to start and/or communicate with a distributed Erlang node. It is built upon the erl_interface library as an example application. Its purpose is to use an Unix shell script to interact with a distributed Erlang node. It performs all communication with the Erlang rex server, using the standard Erlang RPC facility. It does not require any special software to be run at the Erlang target node.
The main use is to either start a distributed Erlang node or to make an ordinary function call. However, it is also possible to pipe an Erlang module to erl_call and have it compiled, or to pipe a sequence of Erlang expressions to be evaluated (similar to the Erlang shell).
See the examples for more details
You can use -eval flag of erl:
$ erl -eval 'io:format("Hello, World!~n")'
You can parse complex arguments with escript:
#!/usr/bin/env escript
main(String) ->
{Node, Mod, Fun, Args} = parse_args(String),
R = rpc:call(Node, Mod, Fun, Args),
io:format("~p~n",[R]).
If your problem is how to set the Erlang node in network mode (i.e. turn the node into a distributed node), you might want to do something like
EPMD = code:root_dir() ++ "/bin/epmd &",
os:cmd(EPMD),
net_kernel:start([Sname, shortnames])
where Sname is your wanted node name. Only after this can you start communicating to another node with e.g. rpc.

Resources