查看源码 shell (stdlib v6.2)
Erlang shell。
shell 是一个用于输入表达式序列的用户界面程序。表达式会被求值并返回一个值。shell 提供了一组类似 Emacs 的快捷键来编辑当前行的文本。有关所有可用快捷键的列表,请参阅 ERTS 用户指南中的 tty - 命令行界面。您也可以更改快捷键以更适合您的偏好,请参阅 edlin - shell 中的行编辑器。
历史机制会保存之前的命令及其值,然后可以在以后的命令中合并使用。要保存的命令和结果的数量可以由用户确定,可以通过交互方式调用 history/1
和 results/1
,或者通过为 STDLIB 应用程序设置应用程序配置参数 shell_history_length
和 shell_saved_results
。可以通过为 Kernel 应用程序设置应用程序配置参数 shell_history
将 shell 历史记录保存到磁盘。
shell 使用一个辅助进程来评估命令,以保护历史机制免受异常的影响。默认情况下,当发生异常时,评估器进程会被杀死,但是通过调用 catch_exception/1
或为 STDLIB 应用程序设置应用程序配置参数 shell_catch_exception
,可以更改此行为。另请参阅下面的示例。
在用户表达式中生成的变量绑定和本地进程字典更改会被保留,并且可以在以后的命令中使用这些变量来访问它们的值。也可以忘记绑定,以便可以重用这些变量。
特殊的 shell 命令都具有(本地)函数调用的语法。它们会被评估为正常的函数调用,并且可以在一个表达式序列中使用多个命令。
如果 shell 无法识别某个命令(本地函数调用),则会首先尝试在模块 user_default
中查找该函数,该模块可以放置自定义的本地命令。如果找到,则会评估该函数,否则会尝试在模块 shell_default
中评估该函数。必须显式加载模块 user_default
。
shell 还允许用户启动多个并发作业。可以将作业视为可以与 shell 通信的一组进程。
shell 对读取和打印记录提供了一些支持。在编译期间,记录表达式会转换为元组表达式。在运行时,无法知道元组是否表示记录,并且编译器使用的记录定义在运行时不可用。因此,为了读取记录语法并在可能的情况下将元组打印为记录,记录定义必须由 shell 本身维护。
下面描述了用于读取、定义、遗忘、列出和打印记录的 shell 命令。请注意,每个作业都有自己的一组记录定义。为了方便起见,每次启动新作业时,都会读取模块 shell_default
和 user_default
(如果已加载)中的记录定义。例如,将以下行添加到 user_default
会使 file_info
的定义在 shell 中立即可用
-include_lib("kernel/include/file.hrl").
shell 在两种模式下运行
正常(可能受限)
模式,可以在其中编辑命令和评估表达式- 作业控制模式,
JCL
,可以在其中启动、杀死、分离和连接作业
只有当前连接的作业才能与 shell“对话”。
Shell 命令
下面的命令是始终可用的内置 shell 命令。在大多数系统中,c
模块中列出的命令也可以在 shell 中使用。
b()
- 打印当前变量绑定。f()
- 删除所有变量绑定。f(X)
- 删除变量X
的绑定。注意
如果变量绑定中存储了一个巨大的值,您必须同时调用
f(X)
和调用history(0)
或results(0)
来释放该内存。h()
- 打印历史记录列表。history(N)
- 将历史记录列表中要保留的先前命令的数量设置为N
。返回先前的数量。默认为 20。results(N)
- 将历史记录列表中要保留的先前命令的结果数量设置为N
。返回先前的数量。默认为 20。e(N)
- 重复命令N
,如果N
为正数。如果为负数,则重复第N
个先前的命令(即,e(-1)
重复上一个命令)。v(N)
- 在当前命令中使用命令N
的返回值,如果N
为正数。如果为负数,则使用第N
个先前命令的返回值(即,v(-1)
使用上一个命令的值)。help()
- 评估shell_default:help()
。h(Module, Function)
- 如果可用,则在 shell 中打印Module:Function
的文档。ht(Module, Type)
- 如果可用,则在 shell 中打印Module:Type
的文档。hcb(Module, Callback)
- 如果可用,则在 shell 中打印Module:Callback
的文档。c(Mod)
- 评估shell_default:c(Mod)
。这将编译和加载模块Mod
并清除旧版本的代码(如果需要)。Mod
可以是模块名称或源文件路径,可以带或不带.erl
扩展名。catch_exception(Bool)
- 设置评估器进程的异常处理。返回先前的异常处理。默认值 (false
) 是在发生异常时杀死评估器进程,这会导致 shell 创建一个新的评估器进程。当异常处理设置为true
时,评估器进程会继续运行。这意味着,例如,端口和 ETS 表以及链接到评估器进程的进程会在异常中存活下来。rd(RecordName, RecordDefinition)
- 在 shell 中定义一个记录。RecordName
是一个原子,RecordDefinition
列出字段名称和默认值。通常,记录定义通过使用下面描述的rr/1,2,3
命令来告知 shell,但有时在运行时定义记录会很方便。rf()
- 删除所有记录定义,然后从模块shell_default
和user_default
(如果已加载)中读取记录定义。返回定义的记录的名称。rf(RecordNames)
- 删除选定的记录定义。RecordNames
是记录名称或记录名称列表。要删除所有记录定义,请使用'_'
。rl()
- 打印所有记录定义。rl(RecordNames)
- 打印选定的记录定义。RecordNames
是记录名称或记录名称列表。rp(Term)
- 使用 shell 已知的记录定义打印一个项。打印Term
的全部内容;深度不受限制,就像打印返回值一样。rr(Module)
- 从模块的 BEAM 文件读取记录定义。如果 BEAM 文件中没有记录定义,则会找到并读取源文件。返回读取的记录定义的名称。Module
是一个原子。rr(Wildcard)
- 从文件读取记录定义。现有读取的任何记录名称的定义都会被替换。Wildcard
是filelib
中定义的通配符字符串,而不是原子。rr(WildcardOrModule, RecordNames)
- 从文件读取记录定义,但会丢弃RecordNames
(记录名称或记录名称列表)中未提及的记录名称。rr(WildcardOrModule, RecordNames, Options)
- 从文件读取记录定义。编译器选项{i, Dir}
、{d, Macro}
和{d, Macro, Value}
被识别并用于设置包含路径和宏定义。要读取所有记录定义,请使用'_'
作为RecordNames
的值。lf()
- 如果存在,则输出带有函数规范的本地定义的函数。lt()
- 输出本地定义的类型。lr()
- 输出本地定义的记录。ff()
- 忘记本地定义的函数(包括函数规范,如果存在)。ff({FunName,Arity})
- 忘记本地定义的函数(包括函数规范,如果存在)。其中FunName
是作为原子的函数名称,Arity
是一个整数。tf()
- 忘记本地定义的类型。tf(Type)
- 忘记本地定义的类型,其中Type
是表示为原子的类型名称。fl()
- 忘记本地定义的函数、类型和记录。save_module(FilePath)
- 将所有本地定义的函数、类型和记录保存到模块文件中,其中FilePath
应包括文件路径和带有.erl
后缀的模块名称。示例:
src/my_module.erl
示例
以下示例是与 shell 的长对话。以 >
开头的命令是 shell 的输入。所有其他行都是来自 shell 的输出。
strider 1> erl
Erlang (BEAM) emulator version 5.3 [hipe] [threads:0]
Eshell V5.3 (abort with ^G)
1> Str = "abcd".
"abcd"
命令 1 将变量 Str
设置为字符串 "abcd"
。
2> L = length(Str).
4
命令 2 将 L
设置为字符串 Str
的长度。
3> Descriptor = {L, list_to_atom(Str)}.
{4,abcd}
命令 3 构建元组 Descriptor
,评估 BIF list_to_atom/1
。
4> L.
4
命令 4 打印变量 L
的值。
5> b().
Descriptor = {4,abcd}
L = 4
Str = "abcd"
ok
命令 5 计算内部 shell 命令 b()
,它是 “bindings”(绑定)的缩写。这会打印当前的 shell 变量及其绑定。ok
是函数 b()
的返回值。
6> f(L).
ok
命令 6 计算内部 shell 命令 f(L)
(“forget”(忘记)的缩写)。变量 L
的值被移除。
7> b().
Descriptor = {4,abcd}
Str = "abcd"
ok
命令 7 打印新的绑定。
8> f(L).
ok
命令 8 无效,因为 L
没有值。
9> {L, _} = Descriptor.
{4,abcd}
命令 9 对 Descriptor
执行模式匹配操作,将新值绑定到 L
。
10> L.
4
命令 10 打印 L
的当前值。
11> {P, Q, R} = Descriptor.
** exception error: no match of right hand side value {4,abcd}
命令 11 尝试将 {P, Q, R}
与 Descriptor
进行匹配,后者是 {4, abc}
。匹配失败,没有新的变量被绑定。以 “** exception error:
” 开头的输出不是表达式的值(表达式因求值失败而没有值),而是系统打印的警告,通知用户发生了错误。其他变量(L
、Str
等)的值保持不变。
12> P.
* 1:1: variable 'P' is unbound
13> Descriptor.
{4,abcd}
命令 12 和 13 表明 P
是未绑定的,因为前一个命令失败了,并且 Descriptor
没有改变。
14>{P, Q} = Descriptor.
{4,abcd}
15> P.
4
命令 14 和 15 显示了正确的匹配,其中 P
和 Q
被绑定。
16> f().
ok
命令 16 清除所有绑定。
接下来的几个命令假设 test1:demo(X)
定义如下:
demo(X) ->
put(aa, worked),
X = 1,
X + 10.
17> put(aa, hello).
undefined
18> get(aa).
hello
命令 17 和 18 设置并检查进程字典中项 aa
的值。
19> Y = test1:demo(1).
11
命令 19 计算 test1:demo(1)
。计算成功,进程字典中所做的更改对 shell 可见。字典项 aa
的新值可以在命令 20 中看到。
20> get().
[{aa,worked}]
21> put(aa, hello).
worked
22> Z = test1:demo(2).
** exception error: no match of right hand side value 1
in function test1:demo/1
命令 21 和 22 将字典项 aa
的值更改为 hello
并调用 test1:demo(2)
。求值失败,并且在发生错误之前对 test1:demo(2)
中的字典所做的更改被丢弃。
23> Z.
* 1:1: variable 'Z' is unbound
24> get(aa).
hello
命令 23 和 24 表明 Z
没有被绑定,并且字典项 aa
保留了其原始值。
25> erase(), put(aa, hello).
undefined
26> spawn(test1, demo, [1]).
<0.57.0>
27> get(aa).
hello
命令 25、26 和 27 显示了在后台计算 test1:demo(1)
的效果。在这种情况下,表达式在新生成的进程中进行计算。在进程字典中所做的任何更改都是新生成进程本地的,因此对 shell 不可见。
28> io:format("hello hello\n").
hello hello
ok
29> e(28).
hello hello
ok
30> v(28).
ok
命令 28、29 和 30 使用 shell 的历史记录功能。命令 29 重新计算命令 28。命令 30 使用命令 28 的值(结果)。在纯函数(没有副作用的函数)的情况下,结果是相同的。对于有副作用的函数,结果可能不同。
接下来的几个命令显示了一些记录操作。假设 ex.erl
定义了一个记录如下:
-record(rec, {a, b = val()}).
val() ->
3.
31> c(ex).
{ok,ex}
32> rr(ex).
[rec]
命令 31 和 32 编译文件 ex.erl
并读取 ex.beam
中的记录定义。如果编译器没有在 BEAM 文件上输出任何记录定义,rr(ex)
将尝试从源文件读取记录定义。
33> rl(rec).
-record(rec,{a,b = val()}).
ok
命令 33 打印名为 rec
的记录的定义。
34> #rec{}.
** exception error: undefined shell command val/0
命令 34 尝试创建一个 rec
记录,但由于函数 val/0
未定义而失败。
35> #rec{b = 3}.
#rec{a = undefined,b = 3}
命令 35 显示了解决方法:显式地将值分配给无法以其他方式初始化的记录字段。
36> rp(v(-1)).
#rec{a = undefined,b = 3}
ok
命令 36 使用 shell 维护的记录定义打印新创建的记录。
37> rd(rec, {f = orddict:new()}).
rec
命令 37 直接在 shell 中定义一个记录。该定义替换了从文件 ex.beam
读取的定义。
38> #rec{}.
#rec{f = []}
ok
命令 38 使用新定义创建一个记录,并打印结果。
39> rd(rec, {c}), A.
* 1:15: variable 'A' is unbound
40> #rec{}.
#rec{c = undefined}
ok
命令 39 和 40 表明记录定义作为副作用更新。命令的计算失败,但是 rec
的定义已经执行。
对于下一个命令,假设 test1:loop(N)
定义如下:
loop(N) ->
io:format("Hello Number: ~w~n", [N]),
loop(N+1).
41> test1:loop(0).
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
命令 41 计算 test1:loop(0)
,这使系统进入无限循环。此时,用户键入 ^G
(Control G),这将暂停当前进程(陷入循环)的输出,并激活 JCL
模式。在 JCL
模式下,用户可以启动和停止作业。
在这种特殊情况下,命令 i
(“interrupt”(中断))终止循环程序,而命令 c
再次连接到 shell。由于该进程在我们杀死它之前在后台运行,因此在显示消息 “** exception exit: killed
” 之前会发生更多打印输出。
42> E = ets:new(t, []).
#Ref<0.1662103692.2407923716.214192>
命令 42 创建一个 ETS 表。
43> ets:insert({d,1,2}).
** exception error: undefined function ets:insert/1
命令 43 尝试将一个元组插入到 ETS 表中,但是缺少第一个参数(表)。该异常会杀死求值器进程。
44> ets:insert(E, {d,1,2}).
** exception error: argument is of wrong type
in function ets:insert/2
called as ets:insert(16,{d,1,2})
命令 44 纠正了错误,但是 ETS 表已被销毁,因为它由被杀死的求值器进程拥有。
45> f(E).
ok
46> catch_exception(true).
false
命令 46 将求值器进程的异常处理设置为 true
。也可以通过 erl -stdlib shell_catch_exception true
在启动 Erlang 时设置异常处理。
47> E = ets:new(t, []).
#Ref<0.1662103692.2407923716.214197>
48> ets:insert({d,1,2}).
* exception error: undefined function ets:insert/1
命令 48 犯了与命令 43 相同的错误,但是这次求值器进程继续存在。打印输出开头的单个星号表示该异常已被捕获。
49> ets:insert(E, {d,1,2}).
true
命令 49 成功地将元组插入到 ETS 表中。
50> ets:insert(#Ref<0.1662103692.2407923716.214197>, {e,3,4}).
true
命令 50 将另一个元组插入到 ETS 表中。这次,第一个参数是表标识符本身。shell 可以解析带有 pid(<0.60.0>
)、端口(#Port<0.536>
)、引用(#Ref<0.1662103692.2407792644.214210>
)和外部函数(#Fun<a.b.1>
)的命令,但是除非可以在运行的系统中创建相应的 pid、端口、引用或函数,否则该命令将失败。
51> halt().
strider 2>
命令 51 退出 Erlang 运行时系统。
JCL 模式
当 shell 启动时,它会启动一个求值器进程。此进程及其生成的任何本地进程都称为一个 作业
。只有当前作业(称为 已连接
)才能执行标准 I/O 操作。所有其他作业(称为 已分离
)如果尝试使用标准 I/O,则会被 阻止
。
所有不使用标准 I/O 的作业都以正常方式运行。
shell 转义键 ^G
(Control G)会分离当前作业并激活 JCL
模式。JCL
模式提示符为 "-->"
。如果在提示符处输入 "?"
,则会显示以下帮助消息:
--> ?
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
JCL
命令具有以下含义:
c [nn]
- 连接到作业编号<nn>
或当前作业。标准 shell 将恢复。当前作业使用的标准 I/O 操作与用户输入到 shell 的操作交错进行。i [nn]
- 停止作业编号nn
或当前作业的当前求值器进程,但不会杀死 shell 进程。因此,任何变量绑定和进程字典都会被保留,并且可以再次连接作业。此命令可用于中断无限循环。k [nn]
- 杀死作业编号nn
或当前作业。作业中所有生成的进程都会被杀死,前提是它们没有评估group_leader/1
BIF 并且位于本地计算机上。在远程节点上生成的进程不会被杀死。j
- 列出所有作业。将打印所有已知作业的列表。当前作业名称的前缀为 '*'。s
- 启动新作业。这将分配新的索引[nn]
,该索引可用于引用。s [shell]
- 启动新作业。这将分配新的索引[nn]
,该索引可用于引用。如果指定了可选参数shell
,则假定它是一个实现替代 shell 的模块。r [node]
- 在node
上启动远程作业。这在分布式 Erlang 中使用,以允许在一个节点上运行的 shell 控制在节点网络上运行的多个应用程序。如果指定了可选参数shell
,则假定它是一个实现替代 shell 的模块。q
- 退出 Erlang。请注意,如果 Erlang 使用忽略中断标志+Bi
启动(例如,在运行受限 shell 时很有用,请参阅下一节),则此选项将被禁用。?
- 显示上面的帮助消息。
可以通过 STDLIB 应用程序变量 shell_esc
更改 shell 转义的行为。该变量的值可以是 jcl
(erl -stdlib shell_esc jcl
) 或 abort
(erl -stdlib shell_esc abort
)。第一个选项将 ^G
设置为激活 JCL
模式(这也是默认行为)。后者将 ^G
设置为终止当前 shell 并启动新的 shell。当 shell_esc
设置为 abort
时,无法调用 JCL
模式。
如果您希望 Erlang 节点从一开始就有一个活动的远程作业(而不是默认的本地作业),请使用标志 -remsh
启动 Erlang,例如 erl -remsh other_node@other_host
受限 Shell
shell 可以在受限模式下启动。在这种模式下,shell 仅在允许的情况下才计算函数调用。此功能使例如可以防止用户从提示符意外调用可能会损害正在运行的系统的函数(与系统标志 +Bi
结合使用很有用)。
当受限 shell 计算表达式并遇到函数调用或运算符应用时,它会调用一个回调函数(其中包含有关相关函数调用的信息)。此回调函数返回 true
以使 shell 继续计算,或返回 false
以中止计算。用户可以实现两个可能的回调函数:
local_allowed(Func, ArgList, State) -> {boolean(),NewState}
这用于确定是否允许调用具有参数
ArgList
的本地函数Func
。non_local_allowed(FuncSpec, ArgList, State) -> {boolean(),NewState} | {{redirect,NewFuncSpec,NewArgList},NewState}
这用于确定是否允许调用具有参数
ArgList
的非本地函数FuncSpec
({Module,Func}
或一个 fun)。返回值{redirect,NewFuncSpec,NewArgList}
可用于让 shell 计算与FuncSpec
和ArgList
指定的函数不同的其他函数。
这些回调函数从本地和非本地求值函数处理程序中调用,这些处理程序在 erl_eval
手册页中描述。(ArgList
中的参数在调用回调函数之前会被求值。)
从 OTP 25.0 开始,如果求值 Erlang 结构时出现错误,例如模式匹配期间的 badmatch
或推导式中的 bad_generator
,求值器将分派到 erlang:raise(error, Reason, Stacktrace)
。此调用将根据 non_local_allowed/3
回调函数进行检查。您可以禁止它、允许它或将其重定向到您选择的另一个调用。
参数 State
是一个元组 {ShellState,ExprState}
。返回值 NewState
具有相同的形式。这可以用于在回调函数的调用之间传递状态。ShellState
中保存的数据在整个 shell 会话中都存在。ExprState
中保存的数据仅在当前表达式的求值过程中存在。
有两种方法可以启动受限 shell 会话
- 使用 STDLIB 应用程序变量
restricted_shell
并将其值指定为回调模块的名称。示例(回调函数在callback_mod.erl
中实现):$ erl -stdlib restricted_shell callback_mod
。 - 从正常的 shell 会话中,调用函数
start_restricted/1
。这将退出当前的求值器并在受限模式下启动一个新的求值器。
注意
- 当受限 shell 模式激活或停用时,节点上启动的新作业分别在受限模式或正常模式下运行。
- 如果特定节点上启用了受限模式,则连接到此节点的远程 shell 也将在受限模式下运行。
- 回调函数不能用于允许或禁止执行从已编译代码调用的函数(仅限从 shell 提示符输入的表达式中调用的函数)。
加载回调模块时的错误会根据受限 shell 的激活方式以不同的方式处理
- 如果在模拟器启动期间通过设置 STDLIB 变量激活受限 shell,并且无法加载回调模块,则会使用默认的受限 shell 作为回退,该 shell 仅允许命令
q()
和init:stop()
。 - 如果使用
start_restricted/1
激活受限 shell,并且无法加载回调模块,则会向错误记录器发送错误报告,并且调用返回{error,Reason}
。
提示
默认的 shell 提示函数会显示节点名称(如果节点可以作为分布式系统的一部分)和当前命令编号。用户可以通过调用 prompt_func/1
或为 STDLIB 应用程序设置应用程序配置参数 shell_prompt_func
来自定义提示函数。类似地,也可以通过调用 multiline_prompt_func/1
或为 STDLIB 应用程序设置应用程序参数 shell_multiline_prompt
来配置多行提示。
自定义的提示函数表示为一个元组 {Mod, Func}
。该函数以 Mod:Func(L)
的形式调用,其中 L
是 shell 创建的键值对列表。当前只有一个键值对:{history, N}
,其中 N
是当前命令编号。该函数应返回字符列表或原子。这是由于 Erlang I/O 协议的约束。在列表和原子中允许使用代码点 255 之外的 Unicode 字符。请注意,在受限模式下,必须允许调用 Mod:Func(L)
,否则将调用默认的 shell 提示函数。
摘要
函数
设置求值器进程的异常处理。返回先前的异常处理。默认值 (false
) 是在发生异常时杀死求值器进程,这会导致 shell 创建一个新的求值器进程。当异常处理设置为 true
时,求值器进程将继续存在,这意味着例如端口和 ETS 表以及链接到求值器进程的进程在异常发生后仍然存在。
将多行提示配置为两个尾随点。这是默认函数,但也可以显式设置为 -stdlib shell_multiline_prompt {shell, default_multiline_prompt}
。
一个格式化函数,可以使用 format_shell_func/1
进行设置,该函数将使提交到 shell 的表达式更美观。
可用于设置 Erlang shell 输出的格式。
将历史记录列表中保留的先前命令数设置为 N
。返回先前的数字。默认为 20。
将多行提示配置为反向空格。可以显式设置为 -stdlib shell_multiline_prompt {shell, inverted_space_prompt}
或调用 multiline_prompt_func({shell, inverted_space_prompt}).
将 shell 多行提示函数设置为 PromptFunc
。返回先前的提示函数。
将 shell 提示函数设置为 PromptFunc
。返回先前的提示函数。
等效于 prompt_width/2
,其中 Encoding
设置为 io:user/0
使用的编码。
它接收提示并计算其宽度,同时考虑其 Unicode 字符和 ANSI 转义。
将历史记录列表中保留的先前命令的结果数设置为 N
。返回先前的数字。默认为 20。
如果尚未启动交互式 shell,则启动它。它可以用于从 escript 或当 erl 使用 -noinput 或 -noshell 标志启动时以编程方式启动 shell。
退出正常的 shell 并启动受限的 shell。Module
指定函数 local_allowed/3
和 non_local_allowed/3
的回调模块。该函数旨在从 shell 中调用。
退出受限的 shell 并启动正常的 shell。该函数旨在从 shell 中调用。
将列表的漂亮打印设置为 Strings
。返回该标志的先前值。
返回调用进程的 group_leader 所在的节点上的当前 shell 进程。如果该节点没有 shell,则此函数将返回 undefined。
函数
设置求值器进程的异常处理。返回先前的异常处理。默认值 (false
) 是在发生异常时杀死求值器进程,这会导致 shell 创建一个新的求值器进程。当异常处理设置为 true
时,求值器进程将继续存在,这意味着例如端口和 ETS 表以及链接到求值器进程的进程在异常发生后仍然存在。
-spec default_multiline_prompt(unicode:chardata()) -> unicode:chardata().
将多行提示配置为两个尾随点。这是默认函数,但也可以显式设置为 -stdlib shell_multiline_prompt {shell, default_multiline_prompt}
。
一个格式化函数,可以使用 format_shell_func/1
进行设置,该函数将使提交到 shell 的表达式更美观。
注意
此格式化函数会从表达式中过滤掉注释。
-spec format_shell_func(ShellFormatFunc) -> ShellFormatFunc2 when ShellFormatFunc :: default | {module(), function()} | string(), ShellFormatFunc2 :: default | {module(), function()} | string().
可用于设置 Erlang shell 输出的格式。
这对已提交的命令以及它在历史记录中的保存方式有影响。或者如果在编辑表达式时按下格式化热键(默认情况下为 Alt-r)。您可以指定一个 Mod:Func/1
,它期望整个表达式作为字符串并返回格式化的表达式作为字符串。有关如何在 shell 启动之前设置它,请参阅 stdlib app config
。
如果改为提供字符串,它将用作 shell 命令。您的命令必须在字符串中的某个位置包含 ${file}
,以便 shell 知道文件在命令中的位置。
shell:format_shell_func("\"emacs -batch \${file} -l ~/erlang-format/emacs-format-file -f emacs-format-function\"").
shell:format_shell_func({shell, erl_pp_format_func}).
-spec history(N) -> non_neg_integer() when N :: non_neg_integer().
将历史记录列表中保留的先前命令数设置为 N
。返回先前的数字。默认为 20。
-spec inverted_space_prompt(unicode:chardata()) -> unicode:chardata().
将多行提示配置为反向空格。可以显式设置为 -stdlib shell_multiline_prompt {shell, inverted_space_prompt}
或调用 multiline_prompt_func({shell, inverted_space_prompt}).
-spec multiline_prompt_func(PromptFunc) -> PromptFunc2 when PromptFunc :: default | {module(), function()} | string(), PromptFunc2 :: default | {module(), function()} | string().
将 shell 多行提示函数设置为 PromptFunc
。返回先前的提示函数。
-spec prompt_func(PromptFunc) -> PromptFunc2 when PromptFunc :: default | {module(), atom()}, PromptFunc2 :: default | {module(), atom()}.
将 shell 提示函数设置为 PromptFunc
。返回先前的提示函数。
-spec prompt_width(unicode:chardata()) -> non_neg_integer().
等效于 prompt_width/2
,其中 Encoding
设置为 io:user/0
使用的编码。
-spec prompt_width(unicode:chardata(), unicode | latin1) -> non_neg_integer().
它接收提示并计算其宽度,同时考虑其 Unicode 字符和 ANSI 转义。
用于创建自定义多行提示。
示例
1> shell:prompt_width("olá> ", unicode).
5
%% "olá> " is printed as "ol\341> " on a latin1 systems
2> shell:prompt_width("olá> ", latin1).
8
%% Ansi escapes are ignored
3> shell:prompt_width("\e[32molá\e[0m> ", unicode).
5
%% Double width characters count as 2
4> shell:prompt_width("😀> ", unicode).
4
%% "😀> " is printed as "\x{1F600}> " on latin1 systems
5> shell:prompt_width("😀> ", latin1).
11
-spec results(N) -> non_neg_integer() when N :: non_neg_integer().
将历史记录列表中保留的先前命令的结果数设置为 N
。返回先前的数字。默认为 20。
-spec start_interactive() -> ok | {error, already_started}.
如果尚未启动交互式 shell,则启动它。它可以用于从 escript 或当 erl 使用 -noinput 或 -noshell 标志启动时以编程方式启动 shell。
-spec start_interactive(noshell | {module(), atom(), [term()]}) -> ok | {error, already_started}; ({remote, string()}) -> ok | {error, already_started | noconnection}; ({node(), {module(), atom(), [term()]}} | {remote, string(), {module(), atom(), [term()]}}) -> ok | {error, already_started | noconnection | badfile | nofile | on_load_failure}.
如果尚未启动交互式 shell,则启动它。它可以用于从 escript
或当 erl
使用 -noinput
或 -noshell
标志启动时以编程方式启动 shell。允许以下选项
noshell - 启动交互式 shell,就好像将
-noshell
传递给了erl
。这仅在 erl 使用-noinput
启动并且系统想要读取输入数据时才有用。{node(), mfa()} - 在
node()
上使用mfa()
作为默认 shell 启动交互式 shell。{remote,
string()
,mfa()
} - 启动交互式 shell,就像给erl
传递了-remsh
参数一样,但使用备选的 shell 实现。
如果发生错误,此函数将返回
already_started - 如果已启动交互式 shell。
noconnection - 如果请求远程 shell,但无法连接。
badfile | nofile | on_load_failure - 如果请求具有自定义 mfa() 的远程 shell,但无法加载模块。 有关错误原因的描述,请参阅代码加载函数的错误原因。
-spec start_restricted(Module) -> {error, Reason} when Module :: module(), Reason :: code:load_error_rsn().
退出正常的 shell 并启动受限的 shell。Module
指定函数 local_allowed/3
和 non_local_allowed/3
的回调模块。该函数旨在从 shell 中调用。
如果无法加载回调模块,则返回错误元组。错误元组中的 Reason
是代码加载器尝试加载回调模块代码时返回的错误原因。
-spec stop_restricted() -> no_return().
退出受限的 shell 并启动正常的 shell。该函数旨在从 shell 中调用。
将列表的漂亮打印设置为 Strings
。返回该标志的先前值。
也可以通过 STDLIB 应用程序变量 shell_strings
设置此标志。默认为 true
,这意味着如果可能,整数列表将使用字符串语法打印。值 false
表示不使用字符串语法打印任何列表。
-spec whereis() -> pid() | undefined.
返回调用进程的 group_leader 所在的节点上的当前 shell 进程。如果该节点没有 shell,则此函数将返回 undefined。