Documentation ¶
Index ¶
- Variables
- type NFS
- func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame map[string]interface{}, table []map[string]string, ...)
- func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server
- func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool
- func (nfs *NFS) Read(p []byte) (n int, err error)
- func (nfs *NFS) Recv(line string) (field string, value string)
- func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS
- func (nfs *NFS) Show(arg ...interface{}) bool
- func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
- func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool
- func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS
Constants ¶
This section is empty.
Variables ¶
View Source
var Index = &ctx.Context{Name: "nfs", Help: "存储中心", Caches: map[string]*ctx.Cache{ "bio": &ctx.Cache{Name: "bio", Value: "0", Help: "文件数量"}, }, Configs: map[string]*ctx.Config{ "term": &ctx.Config{Name: "term", Value: map[string]interface{}{ "use": "false", "mouse": map[string]interface{}{ "resize": false, }, "width": 80, "height": "24", "left": 0, "top": 0, "right": 80, "bottom": 24, "cursor_x": 0, "cursor_y": 0, "fgcolor": -1, "bgcolor": -1, "prompt": "", "wrap": "false", "scroll_count": "5", "scroll_lines": "5", "begin_row": 0, "begin_col": 0, "shadow": "hello", "show_shadow": "false", "rest_fg": "0", "rest_bg": "7", "pick_fg": "0", "pick_bg": "7", "pick": "", "help_index": 0, "help_state": "command", "help_next_auto": "=", "help_stack": []interface{}{}, "help_table": map[string]interface{}{}, }, Help: "终端管理"}, "auto": &ctx.Config{Name: "auto", Value: map[string]interface{}{ "!": map[string]interface{}{ "state": "message", "next_auto": ":", "color": 2, "cmd": "message", "table": "message", "field": "code", "format": "%s(%s) %s->%s %s %s", "fields": []interface{}{"code", "time", "source", "target", "details", "options"}, }, "~": map[string]interface{}{ "state": "context", "next_auto": ":", "color": 2, "cmd": "context", "table": "context", "field": "name", "format": "%s(%s) %s %s", "fields": []interface{}{"name", "status", "stream", "help"}, }, "": map[string]interface{}{ "state": "command", "next_auto": "=", "color": 3, "cmd": "command", "table": "command", "field": "key", "format": "%s %s", "fields": []interface{}{"key", "name"}, }, ":": map[string]interface{}{ "state": "command", "next_auto": "=", "color": 3, "cmd": "command", "table": "command", "field": "key", "format": "%s %s", "fields": []interface{}{"key", "name"}, }, "=": map[string]interface{}{ "cmd": "help", "format": "%s %s %s ", "fields": []interface{}{"value", "name", "help"}, "color": 3, "table": "command", "field": "value", "state": "argument", "next_auto": "=", }, "@": map[string]interface{}{ "state": "config", "next_auto": "@", "color": 4, "cmd": "config", "table": "config", "field": "key", "format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"}, }, "$": map[string]interface{}{ "state": "cache", "next_auto": "$", "color": 7, "cmd": "cache", "table": "cache", "field": "key", "format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"}, }, }, Help: "自动补全"}, "buf": &ctx.Config{Name: "buf", Value: map[string]interface{}{ "size": "81920", }, Help: "文件缓存"}, "grep": &ctx.Config{Name: "grep", Value: map[string]interface{}{}, Help: "文件搜索"}, "git": &ctx.Config{Name: "git", Value: map[string]interface{}{ "args": []interface{}{}, "info": map[string]interface{}{"cmds": []interface{}{"log", "status", "branch"}}, "update": map[string]interface{}{"cmds": []interface{}{"stash", "pull", "pop"}}, "pop": map[string]interface{}{"args": []interface{}{"stash", "pop"}}, "commit": map[string]interface{}{"args": []interface{}{"commit", "-am"}}, "branch": map[string]interface{}{"args": []interface{}{"branch", "-v"}}, "status": map[string]interface{}{"args": []interface{}{"status", "-sb"}}, "log": map[string]interface{}{"args": []interface{}{"log", "-n", "@table.limit", "--skip", "@table.offset", "pretty", "cmd_parse", "cut", "5", "date"}}, "logs": map[string]interface{}{"args": []interface{}{"log", "-n", "@table.limit", "--skip", "@table.offset", "--stat"}}, "trans": map[string]interface{}{ "date": "--date=format:%m/%d %H:%M", "pretty": "--pretty=format:%h %ad %an %s", }, "local": "usr/local", }, Help: "版本管理"}, "dir": &ctx.Config{Name: "dir", Value: map[string]interface{}{ "fields": "time size line path", "type": "both", "temp": "var/tmp/file", "trash": "var/tmp/trash", "mime": map[string]interface{}{ "js": "txt", "css": "txt", "html": "txt", "shy": "txt", "py": "txt", "go": "txt", "h": "txt", "c": "txt", "gz": "bin", }, }, Help: "目录管理"}, "pwd": &ctx.Config{Name: "pwd", Value: []interface{}{ "", "usr/local", "usr", "var", "bin", "etc", "src", "src/plugin", }, Help: "当前目录"}, }, Commands: map[string]*ctx.Command{ "_init": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { m.Conf("pwd", -2, m.Conf("runtime", "boot.ctx_home")) m.Conf("pwd", -2, m.Conf("runtime", "boot.ctx_root")) return }}, "_exit": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { m.Cmd("nfs.term", "exit") return }}, "path": &ctx.Command{Name: "path filename", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { return } file := path.Join(arg...) p := path.Join("src/plugin", m.Option("plugin"), file) if _, e := os.Stat(p); e == nil { m.Echo(p) return e } m.Confm("pwd", func(index int, value string) bool { p := path.Join(value, file) if _, e := os.Stat(p); e == nil { m.Echo(p) return true } return false }) return }}, "pwd": &ctx.Command{Name: "pwd [all] | [[index] path] ", Help: "当前目录,all: 查看所有, index path: 设置路径, path: 设置当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) > 0 && arg[0] == "all" { m.Cmdy("nfs.config", "pwd") return } index := 0 if len(arg) > 1 { index, arg = kit.Int(arg[0]), arg[1:] } for i, v := range arg { m.Log("info", "pwd %s %s", index+i, v) m.Confv("pwd", index+i, v) } if p := m.Conf("pwd", index); path.IsAbs(p) { m.Echo("%s", p) } else if wd, e := os.Getwd(); m.Assert(e) { m.Echo("%s", path.Join(wd, p)) } return }}, "dir": &ctx.Command{Name: "dir [path [fields...]]", Help: []string{ "查看目录, path: 路径, fields...: 查询字段, time|type|full|path|name|tree|size|line|hash|hashs", "dir_deep: 递归查询", "dir_type both|file|dir|all: 文件类型", "dir_reg reg: 正则表达式", "dir_sort field order: 排序"}, Form: map[string]int{"dir_deep": 0, "dir_type": 1, "dir_reg": 1, "dir_sort": 2, "dir_sed": -1, "dir_select": -1, "offset": 1, "limit": 1, "match_begin": 1, "match_end": 1, }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { arg = append(arg, "") } if args := kit.Trans(m.Optionv("dir_sed")); len(args) > 0 { return sed(m, arg[0], args) } mime := m.Conf("dir", []string{"mime", strings.TrimPrefix(path.Ext(arg[0]), ".")}) skip, find := false, false m.Confm("pwd", func(index int, value string) bool { p := kit.Select("./", path.Join(value, arg[0])) if s, e := os.Stat(p); e == nil { if s.IsDir() { rg, _ := regexp.Compile(m.Option("dir_reg")) dir_type := kit.Select(m.Conf("dir", "type"), m.Option("dir_type")) fields := strings.Split(kit.Select(m.Conf("dir", "fields"), strings.Join(arg[1:], " ")), " ") dir(m, kit.Pwd(), p, 0, kit.Right(m.Has("dir_deep")), dir_type, rg, fields, m.Conf("time", "format")) } else if mime != "txt" && (mime == "bin" || s.Size() > int64(m.Confi("buf", "size"))) { m.Append("directory", p) } else { p0 := p + ".tmp0" f, e := os.Open(p0) if e != nil { if f, e = os.Open(p); e == nil { p0 = p } } m.Log("info", "open %v", p0) m.Append("file", p) if m.Has("match_begin") { m.Option("match_begin") begin, _ := regexp.Compile(m.Option("match_begin")) end, _ := regexp.Compile(m.Option("match_end")) start := false for bio := bufio.NewScanner(f); bio.Scan(); { if start = start || begin.MatchString(bio.Text()); m.Option("match_begin") == "" || start { if m.Echo(bio.Text()); m.Option("match_end") != "" && end.MatchString(bio.Text()) { break } } } } else { offset := m.Optioni("offset") limit := m.Optioni("limit") for bio, i := bufio.NewScanner(f), 0; bio.Scan(); i++ { if i >= offset && (limit == 0 || i < offset+limit) { m.Echo(bio.Text()) } m.Append("line", i+1) m.Append("offset", offset) m.Append("limit", limit) } } m.Append("size", s.Size()) m.Append("time", s.ModTime().Format(m.Conf("time", "format"))) skip = true } find = true return true } return false }) if !find && arg[0] != "" { if strings.HasSuffix(arg[0], "/") { m.Assert(os.MkdirAll(arg[0], 0777)) m.Echo(arg[0]) } else if f, p, e := kit.Create(arg[0]); m.Assert(e) { f.Close() m.Echo(p) } } if m.Has("dir_sort") { m.Sort(m.Meta["dir_sort"][0], m.Meta["dir_sort"][1:]...) } if len(m.Meta["append"]) == 1 { for _, v := range m.Meta[m.Meta["append"][0]] { m.Echo(v).Echo(" ") } } else if !skip { if m.Has("dir_select") { m.Cmd("select", m.Meta["dir_select"]) } else { m.Table() } } return }}, "git": &ctx.Command{Name: "git sum", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { m.Cmdy("nfs.config", "git") return } if p := m.Cmdx("nfs.path", arg[0]); p != "" && !m.Confs("git", arg[0]) { m.Option("git_dir", p) arg = arg[1:] } if len(arg) > 0 { switch arg[0] { case "local": m.Cmd("cli.system", "git", "clone", arg[1], "cmd_dir", m.Conf("git", "local")) return case "sum": args := []string{} if m.Options("git_dir") { args = append(args, "-C", m.Option("git_dir")) } if args = append(args, "log", "--shortstat", "--pretty=commit: %ad %n%s", "--date=iso"); len(arg) > 1 { args = append(args, arg[1:]...) } else { args = append(args, "--reverse") } if out, e := exec.Command("git", args...).CombinedOutput(); e == nil { for _, v := range strings.Split(string(out), "commit: ") { if l := strings.Split(v, "\n"); len(l) > 3 { fs := strings.Split(strings.TrimSpace(l[3]), ", ") hs := strings.Split(l[0], " ") m.Add("append", "date", hs[0]) if adds := strings.Split(fs[1], " "); len(fs) > 2 { dels := strings.Split(fs[2], " ") m.Add("append", "adds", adds[0]) m.Add("append", "dels", dels[0]) } else if adds[1] == "insertions(+)" { m.Add("append", "adds", adds[0]) m.Add("append", "dels", "0") } else { m.Add("append", "adds", "0") m.Add("append", "dels", adds[0]) } m.Add("append", "note", l[1]) m.Add("append", "hour", strings.Split(hs[1], ":")[0]) m.Add("append", "time", hs[1]) } else if len(l[0]) > 0 { hs := strings.Split(l[0], " ") m.Add("append", "date", hs[0]) m.Add("append", "adds", 0) m.Add("append", "dels", 0) m.Add("append", "note", l[1]) m.Add("append", "hour", strings.Split(hs[1], ":")[0]) m.Add("append", "time", hs[1]) } } m.Table() } else { m.Log("warn", "%v", string(out)) } return } } cmds := []string{} if v := m.Confv("git", []string{arg[0], "cmds"}); v != nil { cmds = append(cmds, kit.Trans(v)...) } else { cmds = append(cmds, arg[0]) } for _, cmd := range cmds { args := append([]string{}, kit.Trans(m.Confv("git", "args"))...) if m.Options("git_dir") { args = append(args, "-C", m.Option("git_dir")) } if v := m.Confv("git", []string{cmd, "args"}); v != nil { args = append(args, kit.Trans(v)...) } else { args = append(args, cmd) } args = append(args, arg[1:]...) for i, _ := range args { if v := m.Parse(args[i]); v == args[i] || v == "" { args[i] = kit.Select(args[i], m.Conf("git", []string{"trans", args[i]})) } else { args[i] = v } } m.Cmd("cli.system", "git", args).Echo("\n\n").CopyTo(m) } return }}, "template": &ctx.Command{Name: "template [force] target source...", Help: "生成模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { force := false if arg[0] == "force" { force, arg = true, arg[1:] } if _, e := os.Stat(arg[0]); os.IsNotExist(e) || force { if strings.HasSuffix(arg[0], "/") && m.Assert(os.MkdirAll(arg[0], 0777)) { kit.List(arg[1:], func(p string) { m.Cmd("nfs.dir", p, "name", "path").Table(func(line map[string]string) { if w, _, e := kit.Create(path.Join(arg[0], line["name"])); m.Assert(e) { defer w.Close() m.Assert(ctx.ExecuteFile(m, w, line["path"])) } }) }) } else if w, _, e := kit.Create(arg[0]); m.Assert(e) { defer w.Close() kit.List(arg[1:], func(p string) { m.Cmd("nfs.dir", p).Table(func(line map[string]string) { m.Assert(ctx.ExecuteFile(m, w, line["path"])) }) }) } } m.Cmdy("nfs.dir", arg[0], "time", "line", "hashs", "path") return }}, "temp": &ctx.Command{Name: "temp data", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if f, p, e := kit.Create(path.Join(m.Conf("dir", "temp"), kit.Hashs(arg[0]))); m.Assert(e) { defer f.Close() for _, v := range arg { if n, e := f.WriteString(v); e == nil { m.Log("info", "save %v %v", n, p) } } m.Echo(p) } return }}, "hash": &ctx.Command{Name: "hash file", Help: "文件哈希", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { p := m.Append("name", m.Cmdx("nfs.path", arg[0])) if s, e := os.Stat(p); e == nil && !s.IsDir() { m.Append("size", s.Size()) if f, e := os.Open(p); e == nil { defer f.Close() md := md5.New() io.Copy(md, f) h := md.Sum(nil) m.Echo(hex.EncodeToString(h[:])) } } else if f, p, e := kit.Create(path.Join(m.Conf("dir", "temp"), kit.Hashs(arg[0]))); m.Assert(e) { defer f.Close() if n, e := f.WriteString(arg[0]); m.Assert(e) { m.Log("info", "save %v %v", n, p) m.Echo(p) } } return }}, "copy": &ctx.Command{Name: "copy to from", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if to, p, e := kit.Create(arg[0]); m.Assert(e) { defer to.Close() for _, from := range arg[1:] { if f, e := os.Open(m.Cmdx("nfs.path", from)); e == nil { defer f.Close() if n, e := io.Copy(to, f); m.Assert(e) { m.Log("info", "copy %d to %s from %s", n, p, from) } } } m.Echo(p) } return }}, "grep": &ctx.Command{Name: "grep head|tail|hold|more table arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { hold := false switch arg[0] { case "search": m.Cmdy("cli.system", "grep", arg[1:]) case "add": m.Confv("grep", []string{arg[1], "list", "-2"}, map[string]interface{}{ "pos": 0, "offset": 0, "file": arg[2], }) return case "head": m.Confm("grep", []string{arg[1], "list"}, func(index int, value map[string]interface{}) { if len(arg) == 2 { value["offset"] = 0 value["pos"] = 0 } }) return case "tail": m.Confm("grep", []string{arg[1], "list"}, func(index int, value map[string]interface{}) { if len(arg) == 2 { value["pos"] = -1 value["offset"] = 0 } }) return case "hold": hold, arg = true, arg[1:] case "more": hold, arg = false, arg[1:] } m.Confm("grep", []string{arg[0], "list"}, func(index int, value map[string]interface{}) { f, e := os.Open(kit.Format(value["file"])) if e != nil { m.Log("warn", "%v", e) return } defer f.Close() s, e := f.Stat() if e != nil { m.Log("warn", "%v", e) return } offset := kit.Int(value["offset"]) begin, e := f.Seek(int64(kit.Int(value["pos"])), 0) if kit.Int(value["pos"]) == -1 { begin, e = f.Seek(0, 2) } m.Assert(e) file := path.Base(kit.Format(value["file"])) bio := bufio.NewScanner(f) for i := 0; i < m.Optioni("table.limit") && bio.Scan(); i++ { text := bio.Text() if len(arg) == 1 || strings.Contains(text, arg[1]) { m.Add("append", "file", file) m.Add("append", "pos", fmt.Sprintf("%d%%", (begin+int64(len(text)+1))*100/s.Size())) m.Add("append", "line", offset) m.Add("append", "text", text) } else { i-- } begin += int64(len(text)) + 1 offset += 1 } if !hold { value["offset"] = offset value["pos"] = begin } }) m.Table() return }}, "trash": &ctx.Command{Name: "trash file", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { m.Cmdy("nfs.dir", m.Conf("dir", "trash")) return } m.Assert(os.Mkdir(m.Conf("dir", "trash"), 0777)) m.Assert(os.Rename(arg[0], path.Join(m.Conf("dir", "trash"), arg[0]))) return }}, "load": &ctx.Command{Name: "load file [buf_size [pos]]", Help: "加载文件, buf_size: 加载大小, pos: 加载位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if p, f, e := open(m, arg[0]); e == nil { defer f.Close() size := kit.Int(kit.Select(m.Conf("buf", "size"), arg, 1)) if size == -1 { if s, e := f.Stat(); m.Assert(e) { size = int(s.Size()) } } buf := make([]byte, size) pos := kit.Int(kit.Select("0", arg, 2)) if l, e := f.ReadAt(buf, int64(pos)); e == io.EOF || m.Assert(e) { m.Log("info", "load %s %d %d", p, l, pos) m.Echo(string(buf[:l])) } } return }}, "save": &ctx.Command{Name: "save file string...", Help: "保存文件, file: 保存的文件, string: 保存的内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 1 && m.Has("data") { arg = append(arg, m.Option("data")) } if f, p, e := kit.Create(arg[0]); m.Assert(e) { defer f.Close() for _, v := range arg[1:] { if n, e := f.WriteString(v); m.Assert(e) { m.Log("info", "save %s %d", p, n) } } m.Echo(p) } return }}, "import": &ctx.Command{Name: "import filename [index]", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { p, f, e := open(m, arg[0]) m.Assert(e) defer f.Close() s, e := f.Stat() m.Option("filepath", p) m.Option("filename", s.Name()) m.Option("filesize", s.Size()) m.Option("filetime", s.ModTime().Format(m.Conf("time", "format"))) switch { case strings.HasSuffix(arg[0], ".json"): var data interface{} json.NewDecoder(f).Decode(&data) m.Put("option", "filedata", data).Cmdy("ctx.trans", "filedata", arg[1:]).CopyTo(m) case strings.HasSuffix(arg[0], ".csv"): r := csv.NewReader(f) if l, e := r.Read(); m.Assert(e) { m.Meta["append"] = l for l, e = r.Read(); e == nil; l, e = r.Read() { for i, v := range l { m.Add("append", m.Meta["append"][i], v) } } } m.Table() default: if b, e := ioutil.ReadAll(f); m.Assert(e) { m.Echo(string(b)) } } return }}, "export": &ctx.Command{Name: "export filename", Help: "导出数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { tp := false if len(arg) > 0 && arg[0] == "time" { tp, arg = true, arg[1:] } f, p, e := kit.Create(kit.Select(arg[0], m.Format(arg[0]), tp)) m.Assert(e) defer f.Close() data := m.Optionv(kit.Select("data", arg, 1)) if len(arg) > 0 && arg[0] == "all" { data, arg = m.Meta, arg[1:] } switch { case strings.HasSuffix(arg[0], ".json"): if data == nil && len(m.Meta["append"]) > 0 { lines := []interface{}{} nrow := len(m.Meta[m.Meta["append"][0]]) for i := 0; i < nrow; i++ { line := map[string]interface{}{} for _, k := range m.Meta["append"] { line[k] = m.Meta[k][i] } lines = append(lines, line) data = lines } } en := json.NewEncoder(f) en.SetIndent("", " ") en.Encode(data) case strings.HasSuffix(arg[0], ".csv"): fields := m.Meta["append"] if m.Options("fields") { fields = m.Meta["fields"] } if data == nil && len(m.Meta["append"]) > 0 { lines := []interface{}{} nrow := len(m.Meta[m.Meta["append"][0]]) for i := 0; i < nrow; i++ { line := []string{} for _, k := range fields { line = append(line, m.Meta[k][i]) } lines = append(lines, line) data = lines } } if data, ok := data.([]interface{}); ok { w := csv.NewWriter(f) w.Write(fields) for _, v := range data { w.Write(kit.Trans(v)) } w.Flush() } default: f.WriteString(kit.Format(m.Meta["result"])) } m.Set("append").Add("append", "directory", p) m.Set("result").Echo(p) return }}, "json": &ctx.Command{Name: "json str", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { var data interface{} m.Assert(json.Unmarshal([]byte(kit.Select("{}", arg, 0)), &data)) if b, e := json.MarshalIndent(data, "", " "); m.Assert(e) { m.Echo(string(b)) } return }}, "open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if m.Has("io") { } else if p, f, e := open(m, arg[0], os.O_RDWR|os.O_CREATE|os.O_TRUNC); e == nil { m.Put("option", "in", f).Put("option", "out", f) arg[0] = p } else { return nil } m.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), fmt.Sprintf("file %s", arg[0]), "open", arg[0]) m.Append("bio.ctx1", m.Cap("module")) m.Echo(m.Cap("module")) return }}, "read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil { if len(arg) > 1 { m.Cap("pos", arg[1]) } buf := make([]byte, kit.Int(kit.Select(m.Conf("buf", "size"), arg, 0))) if n, e := nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e == io.EOF || m.Assert(e) { m.Capi("nread", n) if m.Capi("pos", n); n == 0 { m.Cap("pos", "0") } } m.Echo(string(buf)) } return }}, "write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil { if len(arg[0]) == 0 { m.Assert(nfs.out.Truncate(int64(m.Capi("pos")))) m.Cap("size", m.Cap("pos")) m.Cap("pos", "0") } else { for _, v := range arg { n, e := nfs.out.WriteAt([]byte(v), int64(m.Capi("pos"))) if m.Capi("nwrite", n); m.Assert(e) && m.Capi("pos", n) > m.Capi("size") { m.Cap("size", m.Cap("pos")) } } nfs.out.Sync() } m.Echo(m.Cap("pos")) } return }}, "source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { m.Cmdy("dir", "src", "time", "line", "path", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$") return } m.Optionv("bio.args", arg) if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" { m.Put("option", "bio.in", os.Stdin).Put("option", "bio.out", os.Stdout) m.Start(arg[0], help, "scan", arg[0]) m.Wait() } else if p, f, e := open(m, arg[0]); e == nil { m.Put("option", "bio.in", f).Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), help, "scan", p) m.Wait() } else { m.Cmdy("yac.parse", strings.Join(arg, " ")+"\n") } return }}, "prompt": &ctx.Command{Name: "prompt arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { nfs.prompt(strings.Join(arg, "")) } return }}, "printf": &ctx.Command{Name: "printf arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { nfs.print(arg...) } return }}, "action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { msg := m.Cmd("nfs.source", arg) nfs.print(msg.Meta["result"]...) } return }}, "term": &ctx.Command{Name: "term action args...", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { nfs.Term(m, arg[0], arg[1:]) } return }}, "socket": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { m.Sess("tcp").Call(func(msg *ctx.Message) *ctx.Message { if msg.Has("node.port") { return msg } msg.Sess("ms_source", msg) msg.Sess("ms_target", m.Source()) msg.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件") return msg }, arg) } return }}, "send": &ctx.Command{Name: "send [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.io != nil { nfs.send <- m.Set("detail", arg) } return }}, }, }
Functions ¶
This section is empty.
Types ¶
Click to show internal directories.
Click to hide internal directories.