当前位置: 首页 > 面试题库 >

如何在Go(golang)中直接调用系统外壳?

阎淮晨
2023-03-14
问题内容

根据golang文档,当您使用exec.Command()时,go不会调用系统的外壳程序。

从“ os / exec”软件包上的golang.org文档中:

与使用C和其他语言进行“系统”库调用不同,os /
exec软件包有意不调用系统外壳程序,并且不展开任何glob模式或处理其他通常由外壳程序完成的扩展,管道或重定向。

这带来了问题。由于这种设计选择,您在执行命令时不能使用管道。因此,以下代码无法按预期执行。

package main

import (
        "fmt"
        "os/exec"
)

func main() {
        exec.Command("echo", "Hello", ">>", "~/thing").Run()
        cmdOut, _ := exec.Command("cat", "~/thing").Output()

        fmt.Println(cmdOut)
}

它不会打印出应包含单词“ Hello”的文件内容,而是打印出空白的换行符。我已经尝试过像这样直接调用bash:

package main

import (
        "fmt"
        "os/exec"
)

func main() {
        exec.Command("bash", "-c", "echo", "Hello", ">>", "~/thing").Run()
        cmdOut, _ := exec.Command("cat", "~/thing").Output()

        fmt.Println(cmdOut)
}

但是,这会产生与原始代码相同的结果。使用golang时如何直接调用系统外壳?


问题答案:

第二个参数应该是一个字符串。在shell命令中,您也需要将其作为一个字符串传递。也~由bash解释。您可以放心地假设它sh存在。Bash
shell不是必须的。

package main

import (                                                                                                                                                                  
 "fmt"                                                                                                                                                                    
 "os/exec"                                                                                                                                                                
)

func main() {                                                                                                                                                             
 exec.Command("sh", "-c", "echo Hello >> ~/thing").Run()                                                                                                                  
 cmdOut, _ := exec.Command("sh", "-c", "cat ~/thing").Output()                                                                                                            
 fmt.Println(cmdOut)                                                                                                                                                      
}


 类似资料:
  • 问题内容: 相对较新。似乎微不足道,但我不知道如何检测操作系统版本。我知道我可以使用并获得平台和体系结构,但是说我知道我在linux上,但是我想确定我是否在RH6上,而在RH7上,等等。 问题答案: 因此,至少在Linux上,软件包中确实存在这种晦涩的方法。它填充的结构有点笨拙,没有文档说明,但是您可以了解它的要点: 顺便说一句,这在操场上不起作用,可能是由于沙箱的限制,但是在Linux上起作用。

  • 问题内容: 我希望能够将go应用程序发出的每次写入/读取记录到底层操作系统,并且(如果可能)将FS完全替换为仅驻留在内存中的FS。 可能吗?怎么样?也许有一个现成的解决方案? 问题答案: 这直接是您(可能)不了解Go的 Andrew Gerrand的10件事: 为此,您需要编写代码以接受参数(也许将其嵌入其他类型,或者表示默认文件系统)。

  • 本文向大家介绍golang实现单点登录系统(go-sso),包括了golang实现单点登录系统(go-sso)的使用技巧和注意事项,需要的朋友参考一下 这是一个基于Go语言开发的单点登录系统,实现手机号注册、手机号+验证码登录、手机号+密码登录、账号登出等功能,用户认证采用cookie和jwt两种方式。收发短信相关方法已提供,仅需根据短信通道提供商提供的接口做相应的参数配置即可使用。 环境介绍 g

  • 问题内容: 我的用户空间应用程序有时会在收到EINTR信号后以某种方式阻塞。 我用strace记录的内容: 我可以捕获EINTR信号吗,如何重复有关的调用,例如写入,读取或选择?即使使用与系统调用一起使用的第三方库,我如何确定EINTR发生在哪里? 为什么收到EINTR后我的应用程序被完全阻止(请参阅strace转储:我发送了SIGUSR1,通常应该处理)?为什么futex()将ERESTARTS

  • 本章描述 Linux 内核中的系统调用概念。 系统调用概念简介 - 介绍 Linux 内核中的系统调用概念 Linux 内核如何处理系统调用 - 介绍 Linux 内核如何处理来自于用户空间应用的系统调用。 vsyscall and vDSO - 介绍 vsyscall 和 vDSO 概念。 Linux 内核如何运行程序 - 介绍一个程序的启动过程。 open 系统调用的实现 - 介绍 open

  • 目标是为每个行添加具有修改时间的列。 鉴于 预期的 我写了一个函数来获取修改时间 修改时间:长=1580708401253 ...但它在查询中不起作用 组织。阿帕奇。火花SparkException:作业因阶段失败而中止:阶段54.0中的任务0失败4次,最近的失败:阶段54.0中的任务0.3丢失(TID 408,srs-hdp-s1.dev.kontur.ru,executor 3):org。阿帕