ejabberd - Running escript from the same context as `ejabberdctl debug` - erlang

Part of setting up my ejabberd server includes running ejabberdctl debug and entering some commands. Instead, I would like to have a file that is executed, but have it run from the same context of the ejabberdctl debug REPL. How can I do this?

You can use the rpc:call command. The Node value is what you see at the debug prompt "name#host".
Also, make sure the escript sets the appropriate cookie value.
Let me clarify, if the debug environment looked like this:
(ejabberd#host)1>
You can create a escript file which looks like this. This updates the log level:
#!/usr/bin/env escript
%%! -sname script1 -setcookie cookie -hidden
main([Level]) ->
rpc:call('ejabberd#host', ejabberd_loglevel, set, [list_to_atom(Level)]).

Related

Erlang VM -s Argument is causing my program to fail

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

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.

starting erlang application with parameter

Is there a way to pass parameters to root supervisor of an application other than with config file and application:get_env/1? For instance, by command line?
I start my app as "erl -pa ebin -run appname", and then communicate with it by TCP/IP. TCP port on which it listens is set in ebin/appname.app, in env part. Now I'd like to be able to tell my app to forget that and listen on a port which I would give on command line (something like "erl -pa ebin -run appname -env [{port, 1234}]"). Is there a standardised pattern for that?
The problem is that I sometimes decide the app should start on another, non default port, for testing purposes, and changing the .app file every time is just pain in the ass.
Regards,
dijxtra
Yes. You can override the value of an environment variable via the command line, using:
erl -appname key value
And retrieving the parameter using:
application:get_env(appname, key).

Run erlang application without terminal depending

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.

Add Path to Erlang Search Path?

I recently installed Erlang RFC4627 (JSON-RPC) with the debian package. I ran the test server using:
sudo erl -pa ebin
and then at the prompt:
test_jsonrpc:start_httpd().
returned
ok
I tested with http://:5671/ and got the success messages.
When I try to run rabbitmq-http2 however, I get the errors that the readme says are caused by rfc4627's code not being on the erlang search path. How do I put it on the path. I saw something on Dave Thomas's blog which suggested putting the path in the file:
~/.erlang
This didn't seem to work for me (maybe I did it wrong?).
The code module is how you manipulate the path within an application.
The flags -pa that you used in starting the Erlang shell actually refer to a function in this module:
add_patha(Dir) -> true | {error, What}
You are right about the .erlang file in your home directory - it is run at start-up time of the shell and you can add in handy paths.
For an application you can start the shell with a batch file that calls something like this:
erl -pa ./ebin ../../lib/some/path/ebin
The flags behaviour of erl is described here.
For more sophisticated path management you need to get familiar with how OTP release management is done (but I suspect that is a while away for you yet).

Resources