Repository navigation
Expand file tree
/
Copy pathshell.go
More file actions
81 lines (73 loc) · 3.38 KB
/
Copy pathshell.go
File metadata and controls
81 lines (73 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package easyshell
import (
"context"
"github.com/3th1nk/easyshell/v2/internal/core"
"github.com/3th1nk/easyshell/v2/record"
)
// Shell 是 CmdShell/SshShell/TelnetShell 的统一抽象,面向"命令交互"场景。
//
// 使用约束:
// - 同一时刻只允许一个读操作在执行(并发 Read/Run 会返回错误);
// - 所有阻塞方法都接受 context,取消/超时通过 context 控制;
// - Close 幂等,调用后所有操作返回 ErrClosed。
type Shell interface {
// Write 写入一行命令,自动在末尾补充 \n;空串等价于写入单个换行
Write(cmd string) error
// WriteRaw 原样写入(不自动补充换行),供密码输入、翻页应答等场景
WriteRaw(p []byte) error
// ReadUntilPrompt 读取输出直到提示符(提示符行默认不作为输出返回)
//
// onOut 在读取流程中同步调用:阻塞它会推迟读取与提示符判定
// (设备可能在等待拦截器应答导致输出停住),需要重处理时请在回调内自行异步化。
// 以下 Read/Run 系列方法的 onOut 语义相同。
ReadUntilPrompt(ctx context.Context, onOut func(lines []string),
opts ...RunOptions) error
// ReadAll 读取全部输出直到流结束
ReadAll(ctx context.Context, onOut func(lines []string),
opts ...RunOptions) error
// Run 写入命令并读取输出直到提示符,等价于 Write + ReadUntilPrompt
Run(ctx context.Context, cmd string, onOut func(lines []string),
opts ...RunOptions) error
// RunAll 写入命令并读取全部输出直到流结束,等价于 Write + ReadAll
RunAll(ctx context.Context, cmd string, onOut func(lines []string),
opts ...RunOptions) error
// Prompt 返回最近一次匹配到的提示符(读取过程中可并发调用)
Prompt() string
// IsPrompt 判断给定内容是否命中提示符规则(并发安全)
IsPrompt(s string) bool
// InConfigMode 基于最近匹配的提示符推断是否处于配置模式(启发式,
// 覆盖 H3C/华为方括号视图与 Cisco (config) 样式;Linux 等返回 false)
InConfigMode() bool
// Close 关闭(幂等)
Close() error
}
// shellBase 非导出委托层:三个 Shell 实现共用,避免样板代码,
// 同时不把 core.Reader 暴露到公共 API。
type shellBase struct {
rw *core.Reader
recorder *record.Writer // 会话录制器(配置了 Record 时非nil,随Close自动收尾)
}
func (b shellBase) Write(cmd string) error { return b.rw.Write(cmd) }
func (b shellBase) WriteRaw(p []byte) error {
return b.rw.WriteRaw(p)
}
func (b shellBase) ReadUntilPrompt(ctx context.Context, onOut func(lines []string),
opts ...RunOptions) error {
return b.rw.ReadUntilPrompt(ctx, onOut, opts...)
}
func (b shellBase) ReadAll(ctx context.Context, onOut func(lines []string),
opts ...RunOptions) error {
return b.rw.ReadAll(ctx, onOut, opts...)
}
func (b shellBase) Run(ctx context.Context, cmd string, onOut func(lines []string),
opts ...RunOptions) error {
return b.rw.Run(ctx, cmd, onOut, opts...)
}
func (b shellBase) RunAll(ctx context.Context, cmd string, onOut func(lines []string),
opts ...RunOptions) error {
return b.rw.RunAll(ctx, cmd, onOut, opts...)
}
func (b shellBase) Prompt() string { return b.rw.Prompt() }
func (b shellBase) IsPrompt(s string) bool { return b.rw.IsPrompt(s) }
func (b shellBase) InConfigMode() bool { return b.rw.InConfigMode() }
func (b shellBase) Close() error { return b.rw.Close() }