go 调用shell命令 两种方式(有无返回值)

2023-05-16

  • 阻塞方式(需要执行结果)
    • 适用于执行普通非阻塞shell命令,且需要shell标准输出的
    • 需要对shell标准输出的逐行实时进行处理的
  • 非阻塞方式(不需要执行结果)
  • 官网的标准中文库

阻塞方式(需要执行结果)

主要用于执行shell命令,并且返回shell的标准输出

适用于执行普通非阻塞shell命令,且需要shell标准输出的

//阻塞式的执行外部shell命令的函数,等待执行完毕并返回标准输出
func exec_shell(s string) (string, error){
    //函数返回一个*Cmd,用于使用给出的参数执行name指定的程序
    cmd := exec.Command("/bin/bash", "-c", s)

    //读取io.Writer类型的cmd.Stdout,再通过bytes.Buffer(缓冲byte类型的缓冲器)将byte类型转化为string类型(out.String():这是bytes类型提供的接口)
    var out bytes.Buffer
    cmd.Stdout = &out

    //Run执行c包含的命令,并阻塞直到完成。  这里stdout被取出,cmd.Wait()无法正确获取stdin,stdout,stderr,则阻塞在那了
    err := cmd.Run()
    checkErr(err)


    return out.String(), err
}

需要对shell标准输出的逐行实时进行处理的

func execCommand(commandName string, params []string) bool {
    //函数返回一个*Cmd,用于使用给出的参数执行name指定的程序
    cmd := exec.Command(commandName, params...)

    //显示运行的命令
    fmt.Println(cmd.Args)
    //StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。
    stdout, err := cmd.StdoutPipe()

    if err != nil {
        fmt.Println(err)
        return false
    }

    cmd.Start()
    //创建一个流来读取管道内内容,这里逻辑是通过一行一行的读取的
    reader := bufio.NewReader(stdout)

    //实时循环读取输出流中的一行内容
    for {
        line, err2 := reader.ReadString('\n')
        if err2 != nil || io.EOF == err2 {
            break
        }
        fmt.Println(line)
    }

    //阻塞直到该命令执行完成,该命令必须是被Start方法开始执行的
    cmd.Wait()
    return true
}

非阻塞方式(不需要执行结果)

通过shell调用自己的程序,并且程序是死循环,此时无法获取返回结果(否则程序会一直阻塞直至调用的 程序结束)

适用于调用自己写的程序(服务器死循环,且不需要返回结果的)

//不需要执行命令的结果与成功与否,执行命令马上就返回
func exec_shell_no_result(command string) {
    //处理启动参数,通过空格分离 如:setsid /home/luojing/gotest/src/test_main/iwatch/test/while_little &
    command_name_and_args := strings.FieldsFunc(command, splite_command)
    //开始执行c包含的命令,但并不会等待该命令完成即返回
    cmd.Start()
        if err != nil {
        fmt.Printf("%v: exec command:%v error:%v\n", get_time(), command, err)
    }
    fmt.Printf("Waiting for command:%v to finish...\n", command)
    //阻塞等待fork出的子进程执行的结果,和cmd.Start()配合使用[不等待回收资源,会导致fork出执行shell命令的子进程变为僵尸进程]
    err = cmd.Wait()
    if err != nil {
        fmt.Printf("%v: Command finished with error: %v\n", get_time(), err)
    }
    return
}
/错误处理函数
func checkErr(err error) {
    if err != nil {
        fmt.Println(err)
        panic(err)  
    }
}

官网的标准中文库

引用部分文档

func (*Cmd) Run
func (c *Cmd) Run() error

Run执行c包含的命令,并阻塞直到完成。
如果命令成功执行,stdinstdoutstderr的转交没有问题,并且返回状态码为0,方法的返回值为nil;如果命令没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。
func (*Cmd) Start
func (c *Cmd) Start() error

Start开始执行c包含的命令,但并不会等待该命令完成即返回。Wait方法会返回命令的返回状态码并在命令返回后释放相关的资源。
func (*Cmd) Wait
func (c *Cmd) Wait() error
Wait会阻塞直到该命令执行完成,该命令必须是被Start方法开始执行的。

如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil;如果命令没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。Wait方法会在命令返回后释放相关的资源。
func (*Cmd) Output
func (c *Cmd) Output() ([]byte, error)
执行命令并返回标准输出的切片。
func (*Cmd) StderrPipe
func (c *Cmd) StderrPipe() (io.ReadCloser, error)
StderrPipe方法返回一个在命令Start后与命令标准错误输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。但是在从管道读取完全部数据之前调用Wait是错误的;同样使用StderrPipe方法时调用Run函数也是错误的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go 调用shell命令 两种方式(有无返回值) 的相关文章

  • bash 脚本中的未绑定变量

    在调试我的脚本时 我变得绝望 我使用了我的高级同事向我推荐的一些结构 但我不知道如何使其正常工作 bin bash x set ueo pipefail exec gt tmp dq log source BASH SOURCE env p
  • shell 脚本中数组的最大元素及其索引

    如何在 shell 脚本中从数组中找到最大元素及其索引 我有一个数组 a 2 2116565098 2 1238242060 2 1747941240 2 3201010162 2 3677779871 1 8126464132 2 124
  • grep 跨文件的最后 n 个匹配

    我正在使用 grep 提取一组文件中的行 grep 一些字符串 log 是否可以将每个文件的最大匹配数限制为每个文件的最后 n 个匹配项 好吧 我认为 grep 不支持限制从文件末尾开始的 N 个匹配 所以这就是你必须做的 ls log w
  • 如何编写bash脚本来设置全局环境变量?

    最近写了一个设置环境变量的脚本 看一下 bin bash echo Pass a path read path echo path defaultPath home whoami Desktop if n path then export
  • 终端从包含空格的变量传递参数

    在终端中如何将包含空格的字符串作为参数传递 它实际上跳过了空格后面的部分 只取第一个单词 word soccer ball shell exec casperjs test js word word 那么我怎样才能转义空白它只运行这个命令
  • 检查 jar 是否从 shell 运行

    我有一个 java jar 程序 我试图在我的机器启动时运行它 理想情况下 shell 脚本将每 60 秒检查一次以确保 jar 正在运行 我如何检查 jar 是否在 centos 上运行 这似乎不起作用 我当前的 sh 文件 bin ba
  • 我收到错误“array.sh:3:array.sh:语法错误:”(“意外”

    我编写了以下代码 bin bash Simple array array 1 2 3 4 5 echo array 我收到错误 array sh 3 array sh 语法错误 意外 根据我从 Google 了解到的情况 这可能是因为 Ub
  • Python 模块 shellquote/unshellquote? [复制]

    这个问题在这里已经有答案了 Python 标准库中是否有任何内容可以正确解析 解解析字符串以在 shell 命令中使用 我正在寻找 perl 的 python 模拟String ShellQuote shell quote print St
  • 如果给定键对应的值以指定字符串开头,则使用 jq 更新 JSON 文档中的对象

    我有给定的 JSON 并想更改id所有元素的值 以test in the name元素 other value some id values name test 2017 12 01 id 1 name othert id 2 以下 jq
  • 具有多个文件扩展名的查找命令

    我正在查看许多子目录 找到所有以 JPG jpg 和 png 结尾的文件 并将它们复制到一个单独的目录中 但是现在只找到 JPG 有人可以解释我做错了什么吗 find root TEST Images name png o name jpg
  • 如何在bash中使用kill SIGUSR2?

    我在linux中使用iptraf来监控网络流量 shell命令是 让iptraf在后台运行 iptraf s eth0 f B L traffic dat 如果我想得到结果 我必须先停止 iptraf 所以我使用 shell 命令 kill
  • Linux shell 根据第二列对文件进行排序?

    我有一个这样的文件 FirstName FamilyName Address PhoneNumber 如何按 FamilyName 排序 如果这是 UNIX sort k 2 file txt 您可以使用多个 k用于对多列进行排序的标志 例
  • Git - 显示远程分支的远程名称

    是否有一个 Git 命令可以显示远程分支的远程名称 目前 我坚持使用 shell utils 从远程分支引用中提取远程名称 例如 echo remote name branch name sed r s 1 remote name 有时出于
  • 在 Linux 中重新启动时,新创建的文件变为 0 kb(数据被覆盖为空)

    我遇到了一个奇怪的问题 这让我发疯 当前的任务是在 root 用户第一次登录时启动一组文件 并在同一用户第二次登录时启动另一组文件 我决定使用 profile 和 bashrc 文件 并在第一次登录期间发生的任务结束时重新加载 bashrc
  • 有哪些基于对象的 shell?

    我打算写一个面向对象的shell 基于Python 我已经有很多想法了 但在实现它之前 我想通过一些现有的 shell 来激发我的灵感 我所说的面向对象的基本意思是 参数不仅仅是字符串数组 而且是对象数组 返回值也是一个对象 不仅有 std
  • unix 下日期字段排序

    我有包含数十万条记录的文本文件 其中一个字段是日期字段 有没有办法根据日期字段对文件进行排序 09 APR 12 04 08 43 632279000 AM 19 MAR 12 03 53 38 189606000 PM 19 MAR 12
  • VBA Shell 并等待退出代码

    我正在打包一个办公应用程序 VBA 它调用 C 控制台应用程序来执行应用程序 大型模拟程序 的一些繁重工作 我希望能够让 VBA 应用程序等待控制台应用程序完成并从控制台应用程序检索退出代码 我已经能够做到前者 但尚未能够从应用程序中检索退
  • 关键字“if”如何测试一个值是真还是假?

    在 bash 脚本中 if 1 then echo Yes else echo No fi Output Yes 它表示 1 被视为真值 但在代码中 word Linux letter nuxi if echo word grep q le
  • shell中如何分割字符串

    我有一个变量作为 string ABC400p2q4 我怎样才能分开ABC400 and p2q4 我需要将它分成两个变量 结果我得到 echo var1 ABC400 echo var2 p2q4 可以用任何字母字符代替 ABC 可以用任
  • 如何制作 Bash 脚本来查找项目中未使用的图像?

    如何制作一个 Bash shell 脚本 它可以识别所有 jpg gif 和 png 文件 然后识别文件夹中任何文本文件中哪些文件未通过 url href 或 src 链接 这就是我开始的 但我最终得到了与我想要的相反的结果 我不想知道引用

随机推荐

  • 本地项目上传到git的详细步骤**

    本地项目上传到git的详细步骤 先进入项目文件夹 xff0c 通过命令git init 把这个目录变成git可以管理的仓库 git init 把文件添加到版本库中 xff0c 使用命令git add 添加到暂存区里面去 xff0c 不要忘记
  • 本地项目上传至git码云步骤

    1 首先在本地配置好Git相关设置 2 在码云上新建一个仓库 xff0c 如图所示 xff0c 可以得到仓库地址 2 在本地需要上传的项目文件夹下鼠标右键选择git bash here xff0c 弹出dos窗口 3 第一步在窗口输入 gi
  • linux 服务器之间文件互传相关命令

    使用scp将一个Linux系统中的文件或文件夹复制到另一台Linux服务器上 一 复制文件 xff1a xff08 1 xff09 将本地文件拷贝到远程 scp 本地文件路径 用户名 64 远程计算机IP或者计算机名称 远程路径 把本地19
  • 【manjaro安装最新的搜狗输入法】2022年1月4号有效测试

    大多数教程都是如下安装 xff1a sudo pacman S fcitx sogoupinyin 但是我的pacman源是没有这个包的 查看yaourt是否有此包 xff1a 21 55 29 steed yaourt Ss fcitx
  • 52单片机设计时钟(串口控制)

    实现目标 单片机时钟正常工作 xff0c 数码管显示时分秒 电脑和单片机串行通信 xff0c 通过电脑串口助手 xff0c 任意修改设置单片机的时钟值 实现的流程框图 运用到的原理有 定时器 计数器 定时器 计数器由高8位和低8位两个寄存器
  • 照片修复-使用Bringing-Old-Photos-Back-to-Life

    项目地址 github项目地址 xff1a https github com microsoft Bringing Old Photos Back to Life 环境搭建 1 下载Bringing Old Photos Back to L
  • cephadm部署分布式ceph存储

    文章目录 一 集群规划系统优化添加yum源挂载本地yum源添加ceph网络yum源添加kernel网络yum源添加docker网络yum源 升级内核部署docker部署时间同步安装ceph引导一个新集群RBD块存储osd 操作打标签监控器调
  • OCR入门教程系列(二):OCR技术发展

    作者简介 CSDN 阿里云人工智能领域博客专家 新星计划计算机视觉导师 百度飞桨PPDE 专注大数据与AI知识分享 公众号 GoAI的学习小屋 免费分享书籍 简历 导图等 更有交流群分享宝藏资料 关注公众号回复 加群 或 链接 加群 专栏推
  • 利用CSS浮动制作一个简易导航栏

    初学CSS 利用CSS浮动和无序列表制作一个简易导航栏 xff1a lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8
  • ERROR Error: Cannot find module ‘vue-loader-v16/package.json‘ vue3.0安装时的错误

    vue3 0 出来一段时间了 xff0c 一直没机会学 xff0c 现在按照网上的教程安装时居然有报错 xff01 我的解决是 直接把项目里面的node modules和package lock json文件删除了 xff0c 然后在重新执
  • php 树形菜单数据获取

    php 树形菜单数据获取 public function generateTree data condition 61 array if empty condition foreach data as k 61 gt v if in arr
  • go语言编译前端静态文件到可执行文件 -statik

    statik 安装 go get github com rakyll statik statik 使用 1 把安装好的包 里面的 statik go 文件编译好 然后运行 2 编译好的statik go文件 src 61 你的静态文件路径
  • goLand全局修改时区

    两种方法 第一种 xff1a loc 61 time FixedZone 34 UTC 34 8 3600 time Local 61 loc 第二种 loc err 61 time LoadLocation 34 America Atka
  • python之Pyperclip模块

    python之Pyperclip模块 下面介绍一下 xff0c python中的Pyperclip模块 xff0c 它的简单又实用 xff0c 主要用法就2点 xff1a 1 用于复制剪贴板里的内容 2 向剪贴板写入内容 一 Pypercl
  • 利用栈判断一个字符串是否是回文

    利用栈判断一个字符串是否是回文 问题描述 编写一个程序 xff0c 判断一个字符串是否为回文 xff08 顺读和倒读都一样的字符串称为回文 xff09 输入形式 长度小于100的任意字符串 输出形式 如果输入字符串是回文 xff0c 则输出
  • Java把String转换成Date类型(Date转换成String类型)

    1 String转换成Date类型 span class token class name SimpleDateFormat span ft span class token operator 61 span span class toke
  • 微信小程序开发自学笔记 —— 七、性能优化

    性能优化 启动 在小程序启动时 xff0c 微信会为小程序展示一个固定的启动界面 xff0c 界面内包含小程序的图标 名称和加载提示图标 此时 xff0c 微信会在背后完成几项工作 xff1a 下载小程序代码包 加载小程序代码包 初始化小程
  • Error: failed to unmarshal json. invalid character “*”looking for beginning of value解决方案

    IPFS config时出现 Error failed to unmarshal json invalid character looking for beginning of value 在Win10 命令行执行ipfs config命令
  • Jsp的四种作用域范围

    首先要声明一点 xff0c 所谓 34 作用域 34 就是 34 信息共享的范围 34 xff0c 也就是说一个信息能够在多大的范围内有效 JSP的四种范围 xff0c 分别为page request session application
  • go 调用shell命令 两种方式(有无返回值)

    阻塞方式 需要执行结果 适用于执行普通非阻塞shell命令 xff0c 且需要shell标准输出的需要对shell标准输出的逐行实时进行处理的 非阻塞方式 不需要执行结果 官网的标准中文库 阻塞方式 需要执行结果 主要用于执行shell命令