diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/stdlib/doc/src/shell.xml | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/stdlib/doc/src/shell.xml')
-rw-r--r-- | lib/stdlib/doc/src/shell.xml | 810 |
1 files changed, 810 insertions, 0 deletions
diff --git a/lib/stdlib/doc/src/shell.xml b/lib/stdlib/doc/src/shell.xml new file mode 100644 index 0000000000..24b845fee9 --- /dev/null +++ b/lib/stdlib/doc/src/shell.xml @@ -0,0 +1,810 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>shell</title> + <prepared>Bjorn Gustavsson</prepared> + <responsible>Bjarne Dacker</responsible> + <docno>1</docno> + <approved>Bjarne Däcker</approved> + <checked></checked> + <date>97-01-24</date> + <rev>A</rev> + <file>shell.sgml</file> + </header> + <module>shell</module> + <modulesummary>The Erlang Shell</modulesummary> + <description> + <p>The module <c>shell</c> implements an Erlang shell. + </p> + <p>The shell is a user interface program + for entering expression sequences. The expressions are + evaluated and a value is returned. + A history mechanism saves previous commands and their + values, which can then be incorporated in later commands. + How many commands and results to save can be determined by the user, + either interactively, by calling <c>shell:history/1</c> and + <c>shell:results/1</c>, or by setting the application configuration + parameters <c>shell_history_length</c> and + <c>shell_saved_results</c> for the application STDLIB. + </p> + <p>The shell uses a helper process for evaluating commands in + order to protect the history mechanism from exceptions. By + default the evaluator process is killed when an exception + occurs, but by calling <c>shell:catch_exception/1</c> or by + setting the application configuration parameter + <c>shell_catch_exception</c> for the application STDLIB + this behavior can be changed. See also the example below. + </p> + <p>Variable bindings, and local process dictionary changes + which are generated in user expressions are preserved, and the variables + can be used in later commands to access their values. The + bindings can also be forgotten so the variables can be re-used. + </p> + <p>The special shell commands all have the syntax of (local) + function calls. They are evaluated as + normal function calls and many commands can be used in one + expression sequence. + </p> + <p>If a command (local function call) is not recognized by the + shell, an attempt is first made to find the function in the + module <c>user_default</c>, where customized local commands + can be placed. If found, then the function is evaluated. + Otherwise, an attempt is made to evaluate the function in the + module <c>shell_default</c>. The module + <c>user_default</c> must be explicitly loaded. + </p> + <p>The shell also permits the user to start multiple concurrent + jobs. A job can be regarded as a set of processes which can + communicate with the shell. + </p> + <p>There is some support for reading and printing records in + the shell. During compilation record expressions are translated + to tuple expressions. In runtime it is not known whether a tuple + actually represents a record. Nor are the record definitions + used by compiler available at runtime. So in order to read the + record syntax and print tuples as records when possible, record + definitions have to be maintained by the shell itself. The shell + commands for reading, defining, forgetting, listing, and + printing records are described below. Note that each job has its + own set of record definitions. To facilitate matters record + definitions in the modules <c>shell_default</c> and + <c>user_default</c> (if loaded) are read each time a new job is + started. For instance, adding the line</p> + <code type="none"> + -include_lib("kernel/include/file.hrl").</code> + <p>to <c>user_default</c> makes the definition of <c>file_info</c> + readily available in the shell. + </p> + <p>The shell runs in two modes: </p> + <list type="bulleted"> + <item><c>Normal (possibly restricted)</c> mode, in which + commands can be edited and expressions evaluated. + </item> + <item>Job Control Mode <c>JCL</c>, in which jobs can be + started, killed, detached and connected. + </item> + </list> + <p>Only the currently connected job can 'talk' to the shell.</p> + </description> + + <section> + <title>Shell Commands</title> + <taglist> + <tag><c>b()</c></tag> + <item> + <p>Prints the current variable bindings.</p> + </item> + <tag><c>f()</c></tag> + <item> + <p>Removes all variable bindings. + </p> + </item> + <tag><c>f(X)</c></tag> + <item> + <p>Removes the binding of variable <c>X</c>. + </p> + </item> + <tag><c>h()</c></tag> + <item> + <p>Prints the history list. + </p> + </item> + <tag><c>history(N)</c></tag> + <item> + <p>Sets the number of previous commands to keep in the + history list to <c>N</c>. The previous number is returned. + The default number is 20. + </p> + </item> + <tag><c>results(N)</c></tag> + <item> + <p>Sets the number of results from previous commands to keep in + the history list to <c>N</c>. The previous number is returned. + The default number is 20. + </p> + </item> + <tag><c>e(N)</c></tag> + <item> + <p>Repeats the command <c>N</c>, if <c>N</c> is positive. If + it is negative, the <c>N</c>th previous command is repeated + (i.e., <c>e(-1)</c> repeats the previous command). + </p> + </item> + <tag><c>v(N)</c></tag> + <item> + <p>Uses the return value of the command <c>N</c> in the + current command, if <c>N</c> is positive. If it is negative, + the return value of the <c>N</c>th previous command is used + (i.e., <c>v(-1)</c> uses the value of the previous command). + </p> + </item> + <tag><c>help()</c></tag> + <item> + <p>Evaluates <c>shell_default:help()</c>. + </p> + </item> + <tag><c>c(File)</c></tag> + <item> + <p>Evaluates <c>shell_default:c(File)</c>. This compiles + and loads code in <c>File</c> and purges old versions of + code, if necessary. Assumes that the file and module names + are the same. + </p> + </item> + <tag><c>catch_exception(Bool)</c></tag> + <item> + <p>Sets the exception handling of the evaluator process. The + previous exception handling is returned. The default + (<c>false</c>) is to kill the evaluator process when an + exception occurs, which causes the shell to create a new + evaluator process. When the exception handling is set to + <c>true</c> the evaluator process lives on which means that + for instance ports and ETS tables as well as processes + linked to the evaluator process survive the exception. + </p> + </item> + <tag><c>rd(RecordName, RecordDefinition)</c></tag> + <item> + <p>Defines a record in the shell. <c>RecordName</c> is + an atom and <c>RecordDefinition</c> lists the field names + and the default values. Usually record definitions are made + known to the shell by use of the <c>rr</c> commands + described below, but sometimes it is handy to define records + on the fly. + </p> + </item> + <tag><c>rf()</c></tag> + <item> + <p>Removes all record definitions, then reads record + definitions from the modules <c>shell_default</c> and + <c>user_default</c> (if loaded). Returns the names of the + records defined. + </p> + </item> + <tag><c>rf(RecordNames)</c></tag> + <item> + <p>Removes selected record definitions. + <c>RecordNames</c> is a record name or a list of record names. + Use <c>'_'</c> to remove all record definitions. + </p> + </item> + <tag><c>rl()</c></tag> + <item> + <p>Prints all record definitions. + </p> + </item> + <tag><c>rl(RecordNames)</c></tag> + <item> + <p>Prints selected record definitions. + <c>RecordNames</c> is a record name or a list of record names. + </p> + </item> + <tag><c>rp(Term)</c></tag> + <item> + <p>Prints a term using the record definitions known to the + shell. All of <c>Term</c> is printed; the depth is not + limited as is the case when a return value is printed. + </p> + </item> + <tag><c>rr(Module)</c></tag> + <item> + <p>Reads record definitions from a module's BEAM file. If + there are no record definitions in the BEAM file, the + source file is located and read instead. Returns the names + of the record definitions read. <c>Module</c> is an atom. + </p> + </item> + <tag><c>rr(Wildcard)</c></tag> + <item> + <p>Reads record definitions from files. Existing + definitions of any of the record names read are replaced. + <c>Wildcard</c> is a wildcard string as defined in + <c>filelib(3)</c> but not an atom. + </p> + </item> + <tag><c>rr(WildcardOrModule, RecordNames)</c></tag> + <item> + <p>Reads record definitions from files but + discards record names not mentioned in <c>RecordNames</c> (a + record name or a list of record names). + </p> + </item> + <tag><c>rr(WildcardOrModule, RecordNames, Options)</c></tag> + <item> + <p>Reads record definitions from files. The compiler + options <c>{i, Dir}</c>, <c>{d, Macro}</c>, and + <c>{d, Macro, Value}</c> are recognized and used + for setting up the include path and macro definitions. Use + <c>'_'</c> as value of <c>RecordNames</c> to read all record + definitions. + </p> + </item> + </taglist> + </section> + + <section> + <title>Example</title> + <p>The following example is a long dialogue with the shell. Commands + starting with <c>></c> are inputs to the shell. All other lines + are output from the shell. All commands in this example are explained at the end of the dialogue. + .</p> + <pre> +strider 1> <input>erl</input> +Erlang (BEAM) emulator version 5.3 [hipe] [threads:0] + +Eshell V5.3 (abort with ^G) +1><input>Str = "abcd".</input> +"abcd" +2> <input>L = length(Str).</input> +4 +3> <input>Descriptor = {L, list_to_atom(Str)}.</input> +{4,abcd} +4> <input>L.</input> +4 +5> <input>b().</input> +Descriptor = {4,abcd} +L = 4 +Str = "abcd" +ok +6> <input>f(L).</input> +ok +7> <input>b().</input> +Descriptor = {4,abcd} +Str = "abcd" +ok +8> <input>f(L).</input> +ok +9> <input>{L, _} = Descriptor.</input> +{4,abcd} +10> <input>L.</input> +4 +11> <input>{P, Q, R} = Descriptor.</input> +** exception error: no match of right hand side value {4,abcd} +12> <input>P.</input> +* 1: variable 'P' is unbound ** +13> <input>Descriptor.</input> +{4,abcd} +14><input>{P, Q} = Descriptor.</input> +{4,abcd} +15> <input>P.</input> +4 +16> <input>f().</input> +ok +17> <input>put(aa, hello).</input> +undefined +18> <input>get(aa).</input> +hello +19> <input>Y = test1:demo(1).</input> +11 +20> <input>get().</input> +[{aa,worked}] +21> <input>put(aa, hello).</input> +worked +22> <input>Z = test1:demo(2).</input> +** exception error: no match of right hand side value 1 + in function test1:demo/1 +23> <input>Z.</input> +* 1: variable 'Z' is unbound ** +24> <input>get(aa).</input> +hello +25> <input>erase(), put(aa, hello).</input> +undefined +26> <input>spawn(test1, demo, [1]).</input> +<0.57.0> +27> <input>get(aa).</input> +hello +28> <input>io:format("hello hello\ ").</input> +hello hello ok +29> <input>e(28).</input> +hello hello ok +30> <input>v(28).</input> +ok +31> <input>c(ex).</input> +{ok,ex} +32> <input>rr(ex).</input> +[rec] +33> <input>rl(rec).</input> +-record(rec,{a,b = val()}). +ok +34> <input>#rec{}.</input> +** exception error: undefined shell command val/0 +35> <input>#rec{b = 3}.</input> +#rec{a = undefined,b = 3} +36> <input>rp(v(-1)).</input> +#rec{a = undefined,b = 3} +ok +37> <input>rd(rec, {f = orddict:new()}).</input> +rec +38> <input>#rec{}.</input> +#rec{f = []} +ok +39> <input>rd(rec, {c}), A.</input> +* 1: variable 'A' is unbound ** +40> <input>#rec{}.</input> +#rec{c = undefined} +ok +41> <input>test1:loop(0).</input> +Hello Number: 0 +Hello Number: 1 +Hello Number: 2 +Hello Number: 3 + +User switch command + --> i + --> c +. +. +. +Hello Number: 3374 +Hello Number: 3375 +Hello Number: 3376 +Hello Number: 3377 +Hello Number: 3378 +** exception exit: killed +42> <input>E = ets:new(t, []).</input> +17 +43> <input>ets:insert({d,1,2}).</input> +** exception error: undefined function ets:insert/1 +44> <input>ets:insert(E, {d,1,2}).</input> +** exception error: argument is of wrong type + in function ets:insert/2 + called as ets:insert(16,{d,1,2}) +45> <input>f(E).</input> +ok +46> <input>catch_exception(true).</input> +false +47> <input>E = ets:new(t, []).</input> +18 +48> <input>ets:insert({d,1,2}).</input> +* exception error: undefined function ets:insert/1 +49> <input>ets:insert(E, {d,1,2}).</input> +true +50> <input>halt().</input> +strider 2></pre> + </section> + + <section> + <title>Comments</title> + <p>Command 1 sets the variable <c>Str</c> to the string + <c>"abcd"</c>. + </p> + <p>Command 2 sets <c>L</c> to the length of the string evaluating + the BIF <c>atom_to_list</c>. + </p> + <p>Command 3 builds the tuple <c>Descriptor</c>. + </p> + <p>Command 4 prints the value of the variable <c>L</c>. + </p> + <p>Command 5 evaluates the internal shell command <c>b()</c>, which + is an abbreviation of "bindings". This prints + the current shell variables and their bindings. The <c>ok</c> at + the end is the return value of the <c>b()</c> function. + </p> + <p>Command 6 <c>f(L)</c> evaluates the internal shell command + <c>f(L)</c> (abbreviation of "forget"). The value of the variable + <c>L</c> is removed. + </p> + <p>Command 7 prints the new bindings. + </p> + <p>Command 8 has no effect since <c>L</c> has no value.</p> + <p>Command 9 performs a pattern matching operation on + <c>Descriptor</c>, binding a new value to <c>L</c>. + </p> + <p>Command 10 prints the current value of <c>L</c>. + </p> + <p>Command 11 tries to match <c>{P, Q, R}</c> against + <c>Descriptor</c> which is <c>{4, abc}</c>. The match fails and + none of the new variables become bound. The printout starting + with "<c>** exception error:</c>" is not the value of the + expression (the expression had no value because its evaluation + failed), but rather a warning printed by the system to inform + the user that an error has occurred. The values of the other + variables (<c>L</c>, <c>Str</c>, etc.) are unchanged. + </p> + <p>Commands 12 and 13 show that <c>P</c> is unbound because the + previous command failed, and that <c>Descriptor</c> has not + changed. + </p> + <p>Commands 14 and 15 show a correct match where <c>P</c> and + <c>Q</c> are bound. + </p> + <p>Command 16 clears all bindings. + </p> + <p>The next few commands assume that <c>test1:demo(X)</c> is + defined in the following way:</p> + <pre> +demo(X) -> + put(aa, worked), + X = 1, + X + 10. </pre> + <p>Commands 17 and 18 set and inspect the value of the item + <c>aa</c> in the process dictionary. + </p> + <p>Command 19 evaluates <c>test1:demo(1)</c>. The evaluation + succeeds and the changes made in the process dictionary become + visible to the shell. The new value of the dictionary item + <c>aa</c> can be seen in command 20. + </p> + <p>Commands 21 and 22 change the value of the dictionary item + <c>aa</c> to <c>hello</c> and call <c>test1:demo(2)</c>. Evaluation + fails and the changes made to the dictionary in + <c>test1:demo(2)</c>, before the error occurred, are discarded. + </p> + <p>Commands 23 and 24 show that <c>Z</c> was not bound and that the + dictionary item <c>aa</c> has retained its original value. + </p> + <p>Commands 25, 26 and 27 show the effect of evaluating + <c>test1:demo(1)</c> in the background. In this case, the + expression is evaluated in a newly spawned process. Any + changes made in the process dictionary are local to the newly + spawned process and therefore not visible to the shell. + </p> + <p>Commands 28, 29 and 30 use the history facilities of the shell. + </p> + <p>Command 29 is <c>e(28)</c>. This re-evaluates command + 28. Command 30 is <c>v(28)</c>. This uses the value (result) of + command 28. In the cases of a pure function (a function + with no side effects), the result is the same. For a function + with side effects, the result can be different. + </p> + <p>The next few commands show some record manipulation. It is + assumed that <c>ex.erl</c> defines a record like this:</p> + <pre> +-record(rec, {a, b = val()}). + +val() -> + 3. </pre> + <p>Commands 31 and 32 compiles the file <c>ex.erl</c> and reads + the record definitions in <c>ex.beam</c>. If the compiler did not + output any record definitions on the BEAM file, <c>rr(ex)</c> + tries to read record definitions from the source file instead. + </p> + <p>Command 33 prints the definition of the record named + <c>rec</c>. + </p> + <p>Command 34 tries to create a <c>rec</c> record, but fails + since the function <c>val/0</c> is undefined. Command 35 shows + the workaround: explicitly assign values to record fields that + cannot otherwise be initialized. + </p> + <p>Command 36 prints the newly created record using record + definitions maintained by the shell. + </p> + <p>Command 37 defines a record directly in the shell. The + definition replaces the one read from the file <c>ex.beam</c>. + </p> + <p>Command 38 creates a record using the new definition, and + prints the result. + </p> + <p>Command 39 and 40 show that record definitions are updated + as side effects. The evaluation of the command fails but + the definition of <c>rec</c> has been carried out. + </p> + <p>For the next command, it is assumed that <c>test1:loop(N)</c> is + defined in the following way:</p> + <pre> +loop(N) -> + io:format("Hello Number: ~w~n", [N]), + loop(N+1).</pre> + <p>Command 41 evaluates <c>test1:loop(0)</c>, which puts the + system into an infinite loop. At this point the user types + <c>Control G</c>, which suspends output from the current process, + which is stuck in a loop, and activates <c>JCL</c> mode. In <c>JCL</c> + mode the user can start and stop jobs. + </p> + <p>In this particular case, the <c>i</c> command ("interrupt") is + used to terminate the looping program, and the <c>c</c> command + is used to connect to the shell again. Since the process was + running in the background before we killed it, there will be + more printouts before the "<c>** exception exit: killed</c>" + message is shown. + </p> + <p>Command 42 creates an ETS table.</p> + <p>Command 43 tries to insert a tuple into the ETS table but the + first argument (the table) is missing. The exception kills the + evaluator process.</p> + <p>Command 44 corrects the mistake, but the ETS table has been + destroyed since it was owned by the killed evaluator process.</p> + <p>Command 46 sets the exception handling of the evaluator process + to <c>true</c>. The exception handling can also be set when + starting Erlang, like this: <c>erl -stdlib shell_catch_exception + true</c>.</p> + <p>Command 48 makes the same mistake as in command 43, but this time + the evaluator process lives on. The single star at the beginning + of the printout signals that the exception has been caught.</p> + <p>Command 49 successfully inserts the tuple into the ETS table.</p> + <p>The <c>halt()</c> command exits the Erlang runtime system. + </p> + </section> + + <section> + <title>JCL Mode</title> + <p>When the shell starts, it starts a single evaluator + process. This process, together with any local processes which + it spawns, is referred to as a <c>job</c>. Only the current job, + which is said to be <c>connected</c>, can perform operations + with standard IO. All other jobs, which are said to be <c>detached</c>, are + <c>blocked</c> if they attempt to use standard IO. + </p> + <p>All jobs which do not use standard IO run in the normal way. + </p> + <p>The shell escape key <em><c>^G</c></em> (Control G) detaches the current job + and activates <c>JCL</c> mode. The <c>JCL</c> mode prompt is <c>"-->"</c>. If <c>"?"</c> is entered at the prompt, the following help message is + displayed:</p> + <pre> + --> ? + c [nn] - connect to job + i [nn] - interrupt job + k [nn] - kill job + j - list all jobs + s [shell] - start local shell + r [node [shell]] - start remote shell + q - quit erlang + ? | h - this message </pre> + <p>The <c>JCL</c> commands have the following meaning:</p> + <taglist> + <tag><c>c [nn]</c></tag> + <item> + <p>Connects to job number <c><![CDATA[<nn>]]></c> or the current + job. The standard shell is resumed. Operations which use + standard IO by the current job will be interleaved with + user inputs to the shell. + </p> + </item> + <tag><c>i [nn]</c></tag> + <item> + <p>Stops the current evaluator process for job number + <c>nn</c> or the current job, but does not kill the shell + process. Accordingly, any variable bindings and the process dictionary + will be preserved and the job can be connected again. + This command can be used to interrupt an endless loop. + </p> + </item> + <tag><c>k [nn]</c></tag> + <item> + <p>Kills job number <c>nn</c> or the current + job. All spawned processes in the job are + killed, provided they have not evaluated the + <c>group_leader/1</c> BIF and are located on + the local machine. Processes spawned on remote nodes will + not be killed. + </p> + </item> + <tag><c>j</c></tag> + <item> + <p>Lists all jobs. A list of all known jobs is + printed. The current job name is prefixed with '*'. + </p> + </item> + <tag><c>s</c></tag> + <item> + <p>Starts a new job. This will be assigned the new index + <c>[nn]</c> which can be used in references. + </p> + </item> + <tag><c>s [shell]</c></tag> + <item> + <p>Starts a new job. This will be assigned the new index + <c>[nn]</c> which can be used in references. + If the optional argument <c>shell</c> is given, it is assumed + to be a module that implements an alternative shell. + </p> + </item> + <tag><c>r [node]</c></tag> + <item> + <p>Starts a remote job on <c>node</c>. This is used in + distributed Erlang to allow a shell running on one node to + control a number of applications running on a network of + nodes. + If the optional argument <c>shell</c> is given, it is assumed + to be a module that implements an alternative shell. + </p> + </item> + <tag><c>q</c></tag> + <item> + <p>Quits Erlang. Note that this option is disabled if + Erlang is started with the ignore break, <c>+Bi</c>, + system flag (which may be useful e.g. when running + a restricted shell, see below). + </p> + </item> + <tag><c>?</c></tag> + <item> + <p>Displays this message.</p> + </item> + </taglist> + <p>It is possible to alter the behavior of shell escape by means + of the STDLIB application variable <c>shell_esc</c>. The value of + the variable can be either <c>jcl</c> (<c>erl -stdlib shell_esc jcl</c>) + or <c>abort</c> (<c>erl -stdlib shell_esc abort</c>). The + first option sets ^G to activate <c>JCL</c> mode (which is also + default behavior). The latter sets ^G to terminate the current + shell and start a new one. <c>JCL</c> mode cannot be invoked when + <c>shell_esc</c> is set to <c>abort</c>. </p> + <p>If you want an Erlang node to have a remote job active from the start + (rather than the default local job), you start Erlang with the + <c>-remsh</c> flag. Example: <c>erl -sname this_node -remsh other_node@other_host</c></p> + </section> + + <section> + <title>Restricted Shell</title> + <p>The shell may be started in a + restricted mode. In this mode, the shell evaluates a function call + only if allowed. This feature makes it possible to, for example, + prevent a user from accidentally calling a function from the + prompt that could harm a running system (useful in combination + with the the system flag <em><c>+Bi</c></em>).</p> + <p>When the restricted shell evaluates an expression and + encounters a function call or an operator application, + it calls a callback function (with + information about the function call in question). This callback + function returns <c>true</c> to let the shell go ahead with the + evaluation, or <c>false</c> to abort it. There are two possible + callback functions for the user to implement:</p> + <p><em><c>local_allowed(Func, ArgList, State) -> {true,NewState} | {false,NewState}</c></em></p> + <p>to determine if the call to the local function <c>Func</c> + with arguments <c>ArgList</c> should be allowed.</p> + <p><em><c>non_local_allowed(FuncSpec, ArgList, State) -> {true,NewState} | {false,NewState} | {{redirect,NewFuncSpec,NewArgList},NewState}</c></em></p> + <p>to determine if the call to non-local function + <c>FuncSpec</c> (<c>{Module,Func}</c> or a fun) with arguments + <c>ArgList</c> should be allowed. The return value + <c>{redirect,NewFuncSpec,NewArgList}</c> can be used to let + the shell evaluate some other function than the one specified by + <c>FuncSpec</c> and <c>ArgList</c>.</p> + <p>These callback functions are in fact called from local and + non-local evaluation function handlers, described in the + <seealso marker="erl_eval">erl_eval</seealso> + manual page. (Arguments in <c>ArgList</c> are evaluated before the + callback functions are called.)</p> + <p>The <c>State</c> argument is a tuple + <c>{ShellState,ExprState}</c>. The return value <c>NewState</c> + has the same form. This may be used to carry a state between calls + to the callback functions. Data saved in <c>ShellState</c> lives + through an entire shell session. Data saved in <c>ExprState</c> + lives only through the evaluation of the current expression.</p> + <p>There are two ways to start a restricted shell session:</p> + <list type="bulleted"> + <item>Use the STDLIB application variable <c>restricted_shell</c> + and specify, as its value, the name of the callback + module. Example (with callback functions implemented in + callback_mod.erl): <c>$ erl -stdlib restricted_shell callback_mod</c></item> + <item>From a normal shell session, call function + <c>shell:start_restricted/1</c>. This exits the current evaluator + and starts a new one in restricted mode.</item> + </list> + <p><em>Notes:</em></p> + <list type="bulleted"> + <item>When restricted shell mode is activated or + deactivated, new jobs started on the node will run in restricted + or normal mode respectively.</item> + <item>If restricted mode has been enabled on a + particular node, remote shells connecting to this node will also + run in restricted mode.</item> + <item>The callback functions cannot be used to allow or disallow + execution of functions called from compiled code (only functions + called from expressions entered at the shell prompt).</item> + </list> + <p>Errors when loading the callback module is handled in different + ways depending on how the restricted shell is activated:</p> + <list type="bulleted"> + <item>If the restricted shell is activated by setting the kernel + variable during emulator startup and the callback module cannot be + loaded, a default restricted shell allowing only the commands + <c>q()</c> and <c>init:stop()</c> is used as fallback.</item> + <item>If the restricted shell is activated using + <c>shell:start_restricted/1</c> and the callback module cannot be + loaded, an error report is sent to the error logger and the call + returns <c>{error,Reason}</c>.</item> + </list> + </section> + <funcs> + <func> + <name>history(N) -> integer()</name> + <fsummary>Sets the number of previous commands to keep</fsummary> + <type> + <v>N = integer()</v> + </type> + <desc> + <p>Sets the number of previous commands to keep in the + history list to <c>N</c>. The previous number is returned. + The default number is 20.</p> + </desc> + </func> + <func> + <name>results(N) -> integer()</name> + <fsummary>Sets the number of previous results to keep</fsummary> + <type> + <v>N = integer()</v> + </type> + <desc> + <p>Sets the number of results from previous commands to keep in + the history list to <c>N</c>. The previous number is returned. + The default number is 20.</p> + </desc> + </func> + <func> + <name>catch_exception(Bool) -> Bool</name> + <fsummary>Sets the exception handling of the shell</fsummary> + <type> + <v>Bool = bool()</v> + </type> + <desc> + <p>Sets the exception handling of the evaluator process. The + previous exception handling is returned. The default + (<c>false</c>) is to kill the evaluator process when an + exception occurs, which causes the shell to create a new + evaluator process. When the exception handling is set to + <c>true</c> the evaluator process lives on which means that + for instance ports and ETS tables as well as processes + linked to the evaluator process survive the exception.</p> + </desc> + </func> + <func> + <name>start_restricted(Module) -> ok | {error, Reason}</name> + <fsummary>Exits a normal shell and starts a restricted shell.</fsummary> + <type> + <v>Module = atom()</v> + <v>Reason = atom()</v> + </type> + <desc> + <p>Exits a normal shell and starts a restricted + shell. <c>Module</c> specifies the callback module for the + functions <c>local_allowed/3</c> and <c>non_local_allowed/3</c>. + The function is meant to be called from the shell.</p> + <p>If the callback module cannot be loaded, an error tuple is + returned. The <c>Reason</c> in the error tuple is the one + returned by the code loader when trying to load the code of the callback + module.</p> + </desc> + </func> + <func> + <name>stop_restricted() -> ok</name> + <fsummary>Exits a restricted shell and starts a normal shell.</fsummary> + <desc> + <p>Exits a restricted shell and starts a normal shell. The function + is meant to be called from the shell.</p> + </desc> + </func> + </funcs> +</erlref> + |