1 Star 0 Fork 0

坐公交也用券/gcs

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
shell.go 4.22 KB
一键复制 编辑 原始数据 按行查看 历史
liumou 提交于 2023-01-30 21:08 . 更新日志模块
package gcs
import (
"fmt"
"os/exec"
"strings"
"gitee.com/liumou_site/gbm"
"github.com/spf13/cast"
)
// RunShell 执行命令并获取执行结果, 返回错误(error)
func (shells *ApiShell) RunShell(command ...string) error {
shells.args = command
shells.shellSystem()
return shells.Err
}
//
//// RunErrOut 执行命令并获取输出数据, 返回执行错误(error)及 命令输出 (字符串)
//func (shells *ApiShell) RunErrOut(command ...string) (out string, err error) {
// shells.args = command
// shells.shellSystem()
// return shells.Strings, shells.Err
//}
//
//// RunSystem 执行命令并实时获取输出,和Python的os.system函数一样,返回退出代码
//func (shells *ApiShell) RunSystem(command ...string) (code int) {
// shells.args = command
// shells.shellSystem()
// return shells.ExitCode
//}
// shellSystem 执行命令并支持实时获取输出,和Python的os.system函数一样,返回退出代码
// command 需要执行的命令 Realtime 是否开启实时打印
func (shells *ApiShell) shellSystem() {
var arg []string
var argTmp string
var cmd *exec.Cmd
shells.Strings = "" // 初始化输出
shells.Result = false // 初始化执行结果
shells.Err = nil // 初始化错误
if len(shells.args) == 1 { // 判断命令参数数量
shells.args = strings.Split(shells.args[0], " ")
}
shells.Text = gbm.SliceToString(shells.args, " ")
commandPath := "/bin/bash" // 定义命令路径
if CheckCmd(shells.args[0]) { // 如果命令在PATH中则使用命令执行并从参数中移除命令
commandPath = shells.args[0] // 使用第一个参数作为命令
shells.args, shells.Err = gbm.SliceRemoveIndex(shells.args, 0) // 移除第一个元素
if shells.Err != nil {
return
}
argTmp = ""
arg = shells.args // 在切片头部添加/C参数
} else {
if shells.OsType == "windows" {
argTmp = "/C"
} else {
argTmp = "-c"
}
if shells.OsType == "windows" {
commandPath = "cmd"
arg = append([]string{argTmp}, shells.args...) // 在切片头部添加/C参数
} else {
arg = append([]string{argTmp}, shells.args...) // 在切片头部添加-c参数
}
}
if len(shells.args) > 0 {
cmd = exec.Command(commandPath, arg...) // 创建命令实例
} else {
cmd = exec.Command(commandPath) // 创建命令实例
}
// 命令的错误输出和标准输出都连接到同一个管道
stdout, err := cmd.StdoutPipe()
cmd.Stderr = cmd.Stdout
shells.Err = err
if err != nil {
shells.logger.Error("管道创建失败")
shells.logger.Debug("Execute command: ", shells.Text)
shells.ExitCode = 1
return
}
shells.Err = cmd.Start()
if shells.Err != nil {
shells.logger.Error("命令启动失败 :", shells.Err)
shells.logger.Debug("Execute command: ", shells.Text)
shells.ExitCode = 2
return
}
// 从管道中实时获取输出并打印到终端
for {
tmp := make([]byte, 1024)
_, err := stdout.Read(tmp)
// 如果开启了实时打印,则将信息逐行输出到终端
if shells.Realtime {
fmt.Print(string(tmp))
}
shells.Strings = shells.Strings + cast.ToString(string(tmp))
if err != nil {
break
}
}
// 等待命令退出,并等待任何复制到stdin或从stdout或stderr复制完成。
shells.Err = cmd.Wait()
// ExitCode返回已退出进程的退出代码,如果进程尚未退出或被信号终止,则返回-1。
shells.ExitCode = cmd.ProcessState.ExitCode()
if shells.Debug {
shells.logger.Info("Exit Code: ", shells.ExitCode)
}
if shells.Err == nil {
if shells.ExitCode != 0 {
shells.logger.Error("Error :", shells.Err)
shells.logger.Debug("Execute command: ", shells.Text)
}
if shells.ExitCode == 0 {
shells.Result = true
shells.Err = nil
}
}
}
//
//// SystemTimeOut 支持设置超时的命令执行函数
//func (shells *ApiShell) SystemTimeOut(cmd string, timeout int) (string, error) {
// ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
// defer cancel()
// args, ok := Shell.Split(cmd) // 对命令进行切割
// // 如果切割失败则返回
// if !ok {
// mess := fmt.Sprintf("unbalanced quotes or backslashes in [%s]", cmd)
// return mess, fmt.Errorf("命令切割失败,请检查是否使用了特殊符号")
// }
// return shells.Execute()
//}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/liumou_site/gcs.git
git@gitee.com:liumou_site/gcs.git
liumou_site
gcs
gcs
v1.5.1

搜索帮助