I am trying to build a script on ubuntu to start some Erlang code of mine:
the script is something like:
#!/bin/sh
EBIN=$HOME/path_to_beams
ERL=/usr/local/bin/erl
export HEART_COMMAND="$EBIN/starting_script start"
case $1 in
start)
$ERL -sname mynode -pa $EBIN \
-heart -detached -s my_module start_link
;;
*)
echo "Usage: $0 {start|stop|debug}"
exit 1
esac
exit 0
but I'm having a couple of problems.
First of all, the code can be executed only if the script is in the same directory as the beams, this seems strange to me, I double checked the paths, so why doesn't the -pa flag work?
Second, the script (without the -pa) works fine, but if I try to start instead of the main module (a gen_server) its supervisor (-s my_module_sup start_link) it doesn't work...this is strange, because if I start the supervisor from a normal shell everything works fine.
Third, the -heart flag, should restart the script in case of failure, but if I kill the process with a normal Unix kill, the process is not restarted.
Can someone give me some hints?
Thanks in advance,
pdn
The first thing that comes to mind is that you're using erlexport instead of erl. Not sure why you're doing this (I've not heard of erlexport before). Try it with erl instead.
Your -heart flag won't have meaning if the Erlang node itself is killed because the process can't keep itself alive. You would need another process running that monitors the Erlang process and restarts it if killed.
Related
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
I have read the thread here: Erlang VM -s argument misbehaving and have been troubleshooting to no avail.
When I run the erlang vm without the -s flag, my function works:
bridge_sup:start_link().
Bridge Supervisor Initializing
[warning] ClientId is NULL!
[warning] ClientId is NULL!
Success
Success
However, if I have the -s flag set, when my function goes on to call another function emqttc:start_link(...) it never returns:
Bridge Supervisor Initializing
[warning] ClientId is NULL!
[warning] ClientId is NULL!
I can verify that it is not just a print problem because the program I am connecting to receives no signal.
What could possibly be causing this in the Erlang VM? I have also tried using eval to the same effect. Here is the ./run code:
erl -pa ebin -pa deps/*/ebin
Thank you in advance!
Could be a startup order problem. Specifying a command to run using -s (or -run or -eval) means that it starts very quickly, while parts of the system may still be starting up in the background. Try adding a sleep at the start of your function and see if it changes anything. In that case, try to figure out what depends on the order.
I am using Erlang version 19.2. I am not sure if this is a bug in this version, or it is a requirement to start a program, but I added a .app.src file and added "-eval 'application:start(myprog)'" and the program will now start!
Note that it did not start with -s, -eval, or any of that without the app.src file and without application:start
I use run_erl to start an erlang application, just like this
run_erl -daemon /tmp/erl_pipe /tmp/erl_log "erl -name 1#127.0.0.1 -setcookie 123456"
Then I Attach to erlang shell like this
to_erl /tmp/erl_pipe
And the question is, I used to quit erlang shell with 'ctrl + c', in this situation, 'ctrl+c' will quit the main node, I have seen my lead to ban this command by modify erlang/OTP source code, how to do that?
Start Erlang as erl +Bi. Note that you'll have to use init:stop() (shortcut q() in the shell) or halt() to stop the node if signals are ignored. Also, the Ctrl-G menu will not have the q option if you use this flag.
It is also possible to use +Bc, which makes Ctrl-C abort the current shell command instead of stopping the whole node. In this case, you can still use q from the Ctrl-G menu.
See http://erlang.org/doc/man/erl.html#emu_flags for the full documentation on runtime system flags.
I need a shell script to send a HUP to the parent and child processes.
I am using freeBSD with tcsh? #/bin/sh
Somehow, I need to pipe the PID output from pgrep to kill -HUP in a loop in a shell script.
Ultimately I want to run this script as a cron job.
I just don't have the skills yet.
Thanks - Brad
(This isn't a complete answer, but I can't make comments without at least 50 reputation apparently).
First of all, /bin/sh on FreeBSD is a Boune-compatible shell, not tcsh (which is /bin/tcsh). A start would be something like the following:
#!/bin/sh
for pid in $(pgrep <process name>); do kill -HUP $pid; done
Without more details, I can't really say much more.
I have erlang application: *.app file and some *.erl files. I compile all of them. In terminal i start erl and there application:start(my_application)., all ok, but if i closed terminal application close too. How can i run application without terminal depending?
Thank you.
You likely want to use the -noshell option to erl. The syntax is
erl -noshell -s Module Function Arguments
So in your case, this might be
erl -noshell -s application start my_application
This should allow you (for example if you are on Unix/Linux) to start your application as a background process and leave it running.
One useful variation is to also call the stop/0 function of the init module so that the Erlang environment will stop when it has finished running your function. This comes in handy if you want to run a simple one-use function and pipe the output to some other process.
So, for example, to pipe to more you could do
erl -noshell -s mymodule myfunction -s init stop | more
Finally, you might also be able to use the escript command to run your Erlang code as scripts rather than compiled code if it makes sense for your situation.
Hope that helps.
The proper way to handle this situation, is building a release containing your app and running the system as so called embedded one.
This release is going to be completely independent (it will hold erts and all the libs like, kernel, std, mnesia etc.).
On start, the new process will not be connected to shell process.
It will be OS process, so you can attach to it with pipes. All script are included in OTP.
Here is some info: http://www.erlang.org/doc/design_principles/release_structure.html
It may seem to be complicated, but tools like rebar do everything for you.