start common node in erlang shell - erlang

Facing problem with slave:start/2 in lion OS, so I have to try another direction "start common node with os:cmd automatically" in erlang shell.
One way is by command directly, and another way is through bash file. But both way faces the same problem. If can't start automatically, I have to start node manually everytime.
Eshell V5.9 (abort with ^G)
(emacs#yus-iMac.local)1> os:cmd("erl -name abcd").
"Eshell V5.9 (abort with ^G)\n(abcd#yus-iMac.local)1> *** Terminating erlang ('abcd#yus-iMac.local')\n"
(emacs#yus-iMac.local)3> os:cmd("~/Documents/Project/node_start").
"Eshell V5.9 (abort with ^G)\n(abc#yus-iMac.local)1> *** Terminating erlang ('abc#yus-iMac.local')\n"
The bash file content is as follows:
#/bin/sh
erl -name abc

Not that I'm really fond of this approach, but to make the above work you should pass the "detached" parameter to the 'erl' command:
erl -name foo
1> os:cmd("erl -name bar -detached").
[]
2> net_adm:ping('bar#pigeon.local').
pong
3> nodes().
['bar#pigeon.local']
Reading from the doc:
-detached
Starts the Erlang runtime system detached from the system console. Useful for running daemons and backgrounds processes. Implies
-noinput.

Related

Cannot use command line Elixir mix (macOS High Sierra)

When i run command elixir -v or mix, it will return:
{"init terminating in do_boot",{undef,[{elixir,start_cli,[],[]},{init,start_em,1,[]},{init,do_boot,3,[]}]}}
Crash dump is being written to: erl_crash.dump...done
init terminating in do_boot ()
Some details:
$ brew list
elixir erlang ...
$ erl
Erlang/OTP 19 [erts-8.0] [source-6dc93c1] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V8.0 (abort with ^G)
1>
$ elixir
Usage: elixir [options] [.exs file] [data]
-e COMMAND Evaluates the given command (*)
-r FILE Requires the given files/patterns (*)
...
I have used brew uninstall, reinstall, but nothing change. Please help me fix it!
erl without any arguments will run Erlang shell. But if you want to run Elixir shell you should try running iex (interactive elixir). elixir is used to run programs you already coded, like elixir simple.exs
Or it might be that your Erlang version is little out of date. Try running brew update.

How does one start an Erlang OTP application and allow the passing of command-line arguments to the application's root supervisor?

Quick 1 liner: How does one start an OTP application and pass command-line args to it?
I wanted be able to start an OTP application in a generic "UNIX" way, being able to pass command-line arguments parsed by getopts. So, I have an erlang escript which uses the getopt library to handle parsing of command-line arguments.
shino's answer got me on the right path:
I have my escript do the getopts parsing
The escript then loads the application description into memory with application:load/1
I then use application:set_env/3 to store the CLI args
Now, launch the application with application:start/2
Once the application launches, the arguments can be accessed via application:get_env/2
You can also override application environment settings on the command line:
erl -myapp foo bar ...
This will set application.get_env(myapp, foo) to "bar", overriding any app.config setting.
You can use init:get_plain_arguments/0 function in order to access command line (extra) arguments.
Example:
$ erl -sname example -extra extra args here
Erlang R15B (erts-5.9) [source] [64-bit] [smp:2:2] [async-threads:0] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
(example#localhost)1> init:get_plain_arguments().
["extra","args","here"]
init:get_plain_argumets/0 returns arguments after -extra option as a list of strings. Option sname is just for explanation, which does not appear in init:get_plain_argumets/0.
For more detail, see document on init module http://www.erlang.org/doc/man/init.html .

open_port doesn't work when `exit_status` option not used

When I call open_port without exit_status in the example below it is unusable:
Eshell V5.7.5 (abort with ^G)
1> P = open_port({spawn, "cat >bar"}, [stream, use_stdio]).
#Port<0.498>
2> port_command(P, "hello\n").
** exception error: bad argument
in function port_command/2
called as port_command(#Port<0.498>,"hello\n")
But when I just add exit_status and leave everything the same it works:
Eshell V5.7.5 (abort with ^G)
1> P = open_port({spawn, "cat >bar"}, [stream, use_stdio, exit_status]).
#Port<0.498>
2> port_command(P, "hello\n").
true
From the documentation I don't understand the difference in behaviour.
When you redirect output in a file in cat >bar command shell closes stdout and Erlang just closes the port in this case because ports try to consume command output by default and close on eof. The right way to fix it is to use out option as butter71 already suggested. Options like out, exit_status, error_to_stdout tell ports to not bother about stdout.
try setting the port for output only:
P = open_port({spawn, "cat >bar"}, [stream, use_stdio, out]).
port_command(P, "hello\n").
my guess is that erlang is unhappy because you redirected the command's stdout.

Erlang. Start remote shell error

I tried to start remote shell and get a following error:
*** ERROR: Shell process terminated! (^G to start new job) ***
Details:
1. Start erlang on a computer a2-x201:
erl -sname a#a2-x201
Erlang R14B (erts-5.8.1) [source] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.8.1 (abort with ^G)
(a#a2-x201)1> nodes().
[]
Start erlang on a computer a2-asrock
erl -sname b#a2-asrock
Establish link between nodes using computer a2-x201:
(a#a2-x201)2> net_adm:ping('b#a2-asrock').
pong
(a#a2-x201)3> nodes().
['b#a2-asrock']
Everything looks ok at the moment.
Starting remote shell on a2-asrock from a2-x201
CTRL+ G
-->r 'b2#a2-asrock'
-->j
1 {shell,start,[init]}
2* {'b2#a2-asrock',shell,start,[]}
-->c
* ERROR: Shell process terminated! (^G to start new job) *
What is wrong?
You are doing remoting on 'b2#a2-asrock' instead of 'b#a2-rock' which is the name of the created node. You're pinging 'b#a2-asrock' but you're trying to connect to 'b2#a2-asrock' instead. Seems that you have a typo in there.

Is there way to run a file with instruction in the erlang shell?

I have a file .erlang in the current dir I run erl shell that compiles a few modules.
Is there way to re run this file from the Erlang shell.
I run erl I get the shell 1> and from there run like run_file(".erlang") and this file execute the instructions in the current shell and load the env.
The file looks like
compile:file(file1).
compile:file(file2).
compile:file(file3).
...
You're looking for file:eval/1.
Given a .erlang with this content:
io:format("Hello world!~n").
You get:
Eshell V5.7.5 (abort with ^G)
1> file:eval(".erlang").
Hello, world!
ok
You might want to look into escript.

Resources