Documentation
¶
Overview ¶
Package shx 提供了基于 mvdan.cc/sh/v3 的纯 Go shell 命令执行功能。
本包是 ShellX 的子包, 提供了与主包相似的 API 风格, 但具有更好的跨平台一致性。 它使用 mvdan.cc/sh/v3 进行命令解析和执行, 不依赖系统 shell。
主要特性:
- 纯 Go 实现, 不依赖系统 shell
- 更好的跨平台一致性 (Windows/Linux/macOS 行为一致)
- 链式调用 API, 支持流畅的方法链
- 支持超时控制和上下文取消
- 最小并发保护 (使用 atomic.Bool 防止重复执行)
基本用法:
import "gitee.com/MM-Q/shellx/shx"
// 简单执行
err := shx.Exec("echo hello world")
// 获取输出
output, err := shx.Output("ls -la")
// 链式配置
output, err := shx.New("echo hello").
WithTimeout(5 * time.Second).
WithDir("/tmp").
ExecOutput()
// 使用上下文
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err := shx.New("long-running-command").WithContext(ctx).Exec()
注意事项:
- Shx 对象的配置方法 (WithXxx) 不是并发安全的, 不要在多个 goroutine 中并发配置
- 每个 Shx 对象只能执行一次, 重复执行会返回错误
- mvdan/sh 是同步执行的, 不提供异步 API, 如需异步请使用 goroutine 包装
- 不支持进程控制 (无 PID、Kill、Signal) , 只能通过 context 取消
Index ¶
- Variables
- func IsExitStatus(err error) (uint8, bool)
- func Out(cmd string) ([]byte, error)
- func OutCtx(ctx context.Context, cmd string) ([]byte, error)
- func OutWith(cmd string, timeout time.Duration) ([]byte, error)
- func OutWithIO(cmd string, stdin io.Reader, stdout, stderr io.Writer) ([]byte, error)
- func Run(cmd string) error
- func RunCtx(ctx context.Context, cmd string) error
- func RunToTerminal(cmd string) error
- func RunWith(cmd string, timeout time.Duration) error
- func RunWithIO(cmd string, stdin io.Reader, stdout, stderr io.Writer) error
- type ExitStatus
- type Shx
- func (s *Shx) Context() context.Context
- func (s *Shx) Dir() string
- func (s *Shx) Env() expand.Environ
- func (s *Shx) Exec() error
- func (s *Shx) ExecContext(ctx context.Context) error
- func (s *Shx) ExecContextOutput(ctx context.Context) ([]byte, error)
- func (s *Shx) ExecOutput() ([]byte, error)
- func (s *Shx) IsExecuted() bool
- func (s *Shx) Raw() string
- func (s *Shx) Timeout() time.Duration
- func (s *Shx) WithContext(ctx context.Context) *Shx
- func (s *Shx) WithDir(dir string) *Shx
- func (s *Shx) WithEnv(key, value string) *Shx
- func (s *Shx) WithEnvMap(envs map[string]string) *Shx
- func (s *Shx) WithEnvs(envs []string) *Shx
- func (s *Shx) WithStderr(w io.Writer) *Shx
- func (s *Shx) WithStdin(r io.Reader) *Shx
- func (s *Shx) WithStdout(w io.Writer) *Shx
- func (s *Shx) WithTimeout(d time.Duration) *Shx
Constants ¶
This section is empty.
Variables ¶
var ( // ErrAlreadyExecuted 表示命令已经执行过 ErrAlreadyExecuted = errors.New("command has already been executed") // ErrNilContext 表示上下文为 nil ErrNilContext = errors.New("context cannot be nil") // ErrNilReader 表示 reader 为 nil ErrNilReader = errors.New("reader cannot be nil") // ErrNilWriter 表示 writer 为 nil ErrNilWriter = errors.New("writer cannot be nil") )
预定义错误
Functions ¶
func Out ¶
Out 执行并获取输出
参数:
- cmd: 命令字符串
返回:
- []byte: 命令输出
- error: 执行错误
示例:
output, err := shx.Out("ls -la")
func OutCtx ¶
OutCtx 使用上下文执行并获取输出
参数:
- ctx: 上下文
- cmd: 命令字符串
返回:
- []byte: 命令输出
- error: 执行错误
示例:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() output, err := shx.OutCtx(ctx, "ls -la")
func OutWith ¶
OutWith 超时执行并获取输出
参数:
- cmd: 命令字符串
- timeout: 超时时间
返回:
- []byte: 命令输出
- error: 执行错误
示例:
output, err := shx.OutWith("sleep 5", 10*time.Second)
func OutWithIO ¶
OutWithIO 使用自定义输入输出执行并获取输出
参数:
- cmd: 命令字符串
- stdin: 标准输入
- stdout: 标准输出
- stderr: 标准错误
返回:
- []byte: 命令输出
- error: 执行错误
示例:
var buf bytes.Buffer
output, err := shx.OutWithIO("cat", strings.NewReader("hello"), &buf, os.Stderr)
func RunCtx ¶
RunCtx 使用上下文执行
参数:
- ctx: 上下文
- cmd: 命令字符串
返回:
- error: 执行错误
示例:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() err := shx.RunCtx(ctx, "sleep 10")
func RunToTerminal ¶
RunToTerminal 执行命令并输出到终端
参数:
- cmd: 命令字符串
返回:
- error: 执行错误
示例:
err := shx.RunToTerminal("echo hello")
Types ¶
type Shx ¶
type Shx struct {
// contains filtered or unexported fields
}
Shx 表示一个待执行的 shell 命令
func New ¶
New 从字符串创建命令
参数:
- cmdStr: 命令字符串
返回:
- *Shx: 命令对象
示例:
cmd := shx.New("echo hello world")
cmd := shx.New("ls -la | grep .go")
func NewArgs ¶
NewArgs 从命令名和可变参数创建命令
参数:
- cmd: 命令名
- args: 可变参数列表
返回:
- *Shx: 命令对象
示例:
cmd := shx.NewArgs("ls", "-la", "/tmp")
cmd := shx.NewArgs("git", "commit", "-m", "message")
func NewCmds ¶
NewCmds 从命令切片创建命令
参数:
- cmds: 命令切片,每个元素是一个完整的命令部分
返回:
- *Shx: 命令对象
示例:
cmd := shx.NewCmds([]string{"ls", "-la", "|", "grep", ".go"})
cmd := shx.NewCmds([]string{"echo", "hello", ">", "output.txt"})
func (*Shx) Exec ¶
Exec 执行命令 (阻塞)
返回:
- error: 执行过程中的错误, 不包含退出码错误
线程安全:
- 使用 atomic.Bool 确保重复执行检测的线程安全
示例:
err := shx.New("echo hello").Exec()
if err != nil {
log.Fatal(err)
}
func (*Shx) ExecContext ¶
ExecContext 在指定上下文中执行命令
参数:
- ctx: 上下文 (用于取消执行)
返回:
- error: 执行过程中的错误
注意:
- 此方法会覆盖之前通过 WithContext 设置的上下文
- 此方法不受 WithTimeout 影响 (上下文的超时优先)
func (*Shx) ExecContextOutput ¶
ExecContextOutput 在指定上下文中执行并返回输出
参数:
- ctx: 上下文
返回:
- []byte: 命令输出
- error: 执行过程中的错误
func (*Shx) ExecOutput ¶
ExecOutput 执行命令并返回输出
返回:
- []byte: 命令输出 (stdout 和 stderr 合并)
- error: 执行过程中的错误
注意:
- 内部会自动捕获 stdout 和 stderr
- 如果需要区分 stdout 和 stderr, 请使用 WithStdout 和 WithStderr 自定义
func (*Shx) WithContext ¶
WithContext 设置上下文
参数:
- ctx: 上下文
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic
- 设置的上下文会完全覆盖 WithTimeout 设置的超时
func (*Shx) WithDir ¶
WithDir 设置工作目录
参数:
- dir: 工作目录路径
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic
- 如果目录不存在或不是目录, 会 panic
func (*Shx) WithEnv ¶
WithEnv 设置环境变量
参数:
- key: 环境变量名
- value: 环境变量值
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic
- 如果 key 为空, 则忽略
func (*Shx) WithEnvMap ¶ added in v1.0.14
WithEnvMap 批量设置环境变量
参数:
- envs: 环境变量映射 (key-value)
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic
func (*Shx) WithEnvs ¶
WithEnvs 批量设置环境变量
参数:
- envs: 环境变量切片, 每个元素格式为 "key=value"
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic
- 格式错误的项会被忽略
- 同名的变量, 后出现的会覆盖先出现的
func (*Shx) WithStderr ¶
WithStderr 设置标准错误
参数:
- w: 错误输出写入器
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic
func (*Shx) WithStdin ¶
WithStdin 设置标准输入
参数:
- r: 输入读取器
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic
func (*Shx) WithStdout ¶
WithStdout 设置标准输出
参数:
- w: 输出写入器
返回:
- *Shx: 命令对象 (支持链式调用)
注意:
- 如果命令已经执行过, 会 panic