api

func (*Cmd) Run
func (c *Cmd) Run() errorRun执行c包含的命令,并阻塞直到完成。
如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil;如果命令没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。
func (*Cmd) Start
func (c *Cmd) Start() errorStart开始执行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函数也是错误的。

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

主要用于执行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.Buffercmd.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)  }
}

ssh

go get golang.org/x/crypto/ssh

ssh执行命令

这个方法需要有一个环境的准备:与目标服务器建立免密码登陆],并且执行程序的用户与执行用户一致

import ("net""log""fmt""bytes""os/exec""strconv"str "strings""golang.org/x/crypto/ssh"
)func runCmd(){var stdOut, stdErr bytes.Buffercmd := exec.Command( "ssh", "username@192.168.1.4", "if [ -d liujx/project ];then echo 0;else echo 1;fi" )cmd.Stdout = &stdOutcmd.Stderr = &stdErrif err := cmd.Run(); err != nil {fmt.Printf( "cmd exec failed: %s : %s", fmt.Sprint( err ), stdErr.String() )}fmt.Print( stdOut.String() )ret, err := strconv.Atoi( str.Replace( stdOut.String(), "\n", "", -1 )  )if err != nil {panic(err)}fmt.Printf("%d, %s\n", ret, stdErr.String() )
}

ssh客户端连接

这种方法可以不用搭建免密码登陆环境,连接时可指定用户和密码的

func SSHConnect( user, password, host string, port int ) ( *ssh.Session, error ) {var (auth         []ssh.AuthMethodaddr         stringclientConfig *ssh.ClientConfigclient       *ssh.Clientsession      *ssh.Sessionerr          error)// get auth methodauth = make([]ssh.AuthMethod, 0)auth = append(auth, ssh.Password(password))hostKeyCallbk := func(hostname string, remote net.Addr, key ssh.PublicKey) error {return nil}clientConfig = &ssh.ClientConfig{User:               user,Auth:               auth,// Timeout:             30 * time.Second,HostKeyCallback:    hostKeyCallbk, }// connet to sshaddr = fmt.Sprintf( "%s:%d", host, port )if client, err = ssh.Dial( "tcp", addr, clientConfig ); err != nil {return nil, err}// create sessionif session, err = client.NewSession(); err != nil {return nil, err}return session, nil
}func runSsh(){var stdOut, stdErr bytes.Buffersession, err := SSHConnect( "username", "passworld", "192.168.1.4", 22 )if err != nil {log.Fatal(err)}defer session.Close()session.Stdout = &stdOutsession.Stderr = &stdErrsession.Run("if [ -d liujx/project ]; then echo 0; else echo 1; fi")ret, err := strconv.Atoi( str.Replace( stdOut.String(), "\n", "", -1 )  )if err != nil {panic(err)}fmt.Printf("%d, %s\n", ret, stdErr.String() )}

os.Args

func main() {osArg := os.Args   //[]string/**o 开始,第一个是文件路径*/for i, data := range osArg {fmt.Println(i, data)}
}

flag命令行参数

每个处理一行

func main() {var recusive boolvar test stringvar level intflag.BoolVar(&recusive, "r", false, "recusive xxx")flag.StringVar(&test, "t","default string", "string option")flag.IntVar(&level, "l", 1, "level of xxx")flag.Parse()fmt.Println(recusive)fmt.Println(test)fmt.Println(level)
}

不传就给默认值

➜  studygo ./studygo
false
default string
1

传递就按照传递的来

➜  studygo ./studygo -r -t hello -l 11
true
hello
11

urfave/cli框架

可以通过-h查看帮助

import ("fmt""github.com/urfave/cli""os"
)func main() {var language stringvar recusive boolapp := cli.NewApp()//指定名字app.Name = "greet"app.Usage = "用法"app.Flags = []cli.Flag{cli.StringFlag{Name:        "lang, l",Value:       "english",Usage:       "select language",Destination: &language,},cli.BoolFlag{Name:        "recusive, r",Usage:       "recusive for the greeting",Destination: &recusive,},}app.Action = func(c *cli.Context) error {var cmd string//如果用户传过来 >0if c.NArg() > 0 {cmd = c.Args()[0]fmt.Println("cmd is ", cmd)}fmt.Println("recusive is: ", recusive)fmt.Println("language is: ", language)return nil}app.Run(os.Args)
}

启动外部命令和程序

os 包有一个StartProcess函数可以调用或启动外部系统命令和二进制可执行文件;它的第一个参数是要运行的进程,第二个参数用来传递选项或参数,第三个参数是含有系统环境基本信息的结构体。

这个函数返回被启动进程的 id(pid),或者启动失败返回错误。

exec 包中也有同样功能的更简单的结构体和函数;主要是exec.Command(name string, arg ...string)Run()。首先需要用系统命令或可执行文件的名字创建一个Command对象,然后用这个对象作为接收者调用Run()。下面的程序(因为是执行 Linux 命令,只能在 Linux 下面运行)演示了它们的使用:

// exec.go
package main
import ("fmt""os/exec""os"
)func main() {
// 1) os.StartProcess //
/*********************/
/* Linux: */
env := os.Environ()
procAttr := &os.ProcAttr{Env: env,Files: []*os.File{os.Stdin,os.Stdout,os.Stderr,},}
// 1st example: list files
pid, err := os.StartProcess("/bin/ls", []string{"ls", "-l"}, procAttr)
if err != nil {fmt.Printf("Error %v starting process!", err)  //os.Exit(1)
}
fmt.Printf("The process id is %v", pid)

输出:

The process id is &{2054 0}total 2056
-rwxr-xr-x 1 ivo ivo 1157555 2011-07-04 16:48 Mieken_exec
-rw-r--r-- 1 ivo ivo    2124 2011-07-04 16:48 Mieken_exec.go
-rw-r--r-- 1 ivo ivo   18528 2011-07-04 16:48 Mieken_exec_go_.6
-rwxr-xr-x 1 ivo ivo  913920 2011-06-03 16:13 panic.exe
-rw-r--r-- 1 ivo ivo     180 2011-04-11 20:39 panic.go
// 2nd example: show all processes
pid, err = os.StartProcess("/bin/ps", []string{"-e", "-opid,ppid,comm"}, procAttr)  if err != nil {fmt.Printf("Error %v starting process!", err)  //os.Exit(1)
}fmt.Printf("The process id is %v", pid)
// 2) exec.Run //
/***************/
// Linux:  OK, but not for ls ?
// cmd := exec.Command("ls", "-l")  // no error, but doesn't show anything ?
// cmd := exec.Command("ls")        // no error, but doesn't show anything ?cmd := exec.Command("gedit")  // this opens a gedit-windowerr = cmd.Run()if err != nil {fmt.Printf("Error %v executing command!", err)os.Exit(1)}fmt.Printf("The command is %v", cmd)
// The command is &{/bin/ls [ls -l] []  <nil> <nil> <nil> 0xf840000210 <nil> true [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [] [] 0xf8400128c0}
}
// in Windows: uitvoering: Error fork/exec /bin/ls: The system cannot find the path specified. starting process!

golang中的shell相关推荐

  1. linux 脚本 lang,golang可以编写shell脚本吗

    golang可以编写shell脚本吗 golang是可以编写shell脚本,首先可以通过创建一个阅读器去访问键盘,每当按下回车键时,任何的写入都会被存储到输入变量中:然后根据出入的数据来执行逻辑运算: ...

  2. Golang中Buffer高效拼接字符串以及自定义线程安全Buffer

    本文原创文章,转载注明出处,博客地址 https://segmentfault.com/u/to... 第一时间看后续精彩文章.觉得好的话,顺手分享到朋友圈吧,感谢支持. Go中可以使用"+ ...

  3. 如何在golang中关闭bufio.reader_Golang 并发模型系列:1. 轻松入门流水线模型

    Go语言中文网,致力于每日分享编码.开源等知识,欢迎关注我,会有意想不到的收获! Golang作为一个实用主义的编程语言,非常注重性能,在语言特性上天然支持并发,它有多种并发模型,通过流水线模型系列文 ...

  4. Linux中执行shell脚本的4种方法

    这篇文章主要介绍了Linux中执行shell脚本的4种方法总结,即在Linux中运行shell脚本的4种方法,需要的朋友可以参考下. bash shell 脚本的方法有多种,现在作个小结.假设我们编写 ...

  5. linux默认csh修改命令,Solaris中默认Shell的修改以及命令行补全的设置

    Solaris中默认Shell的修改以及命令行补全的设置 发布时间:2008-02-18 00:01:41来源:红联作者:qtsmy Solaris10 x86虽然可以跑起来,但有很多方面都用这和以前 ...

  6. go语言的iota是什么意思_关于Golang中的iota

    快速一览 iota是Golang中提供的一个简化常量和枚举编程的标识符,合理的使用这个标识符可以让代码变得更简洁,省去大量的不必要的代码. 比如下面的这个常量定义 const ( a = 1 b = ...

  7. Golang中的panic和recover(捕获异常)

    Golang中的panic和recover(捕获异常) 参考文章: (1)Golang中的panic和recover(捕获异常) (2)https://www.cnblogs.com/zhzhlong ...

  8. golang 中string和int类型相互转换

    总结了golang中字符串和各种int类型之间的相互转换方式: string转成int: test_int, err := strconv.Atoi(test_string) if err != ni ...

  9. vim中执行shell命令小结

    vim中执行shell命令,有以下几种形式 1):!command 不退出vim,并执行shell命令command,将命令输出显示在vim的命令区域,不会改变当前编辑的文件的内容 例如 :!ls - ...

最新文章

  1. sqlserver中索引优化
  2. POJ 3040 Allowance【贪心】
  3. VC使用HTTP协议下载文件
  4. 金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-(一千零一拾一元整)输出。...
  5. GB/T 17710-1999 PHP生成校验码
  6. 一个@Transaction哪里来这么多坑?
  7. kafka 集群_kafka 集群及原理
  8. ubuntu系统安装python hello_ubuntu 下python安装及hello world
  9. shell字符串长度
  10. iOS中滤镜处理及相关内存泄漏问题的解决
  11. Oracle全备增量备份脚本,ORACLE-RMAN:备份脚本(全库,增量)
  12. android 8.1闪退,宁波市民卡app在Android 8.1闪退_宁波民生e点通
  13. [转载] Python进程——multiprocessing.Event()|Barrier()
  14. python 生成器_彻底理解 Python 生成器
  15. 推荐一个好用的百度文库在线免费下载文档网站
  16. Java实现智能对话机器人自动聊天+语音秒回
  17. word怎么转pdf,word批量转pdf方法
  18. 种子软件下载种子慢怎么解决
  19. python飞机大战实验报告心得_飞机大战实训报告
  20. 2021年软考考试时间确定

热门文章

  1. 【MATLAB】matlab 文档使用 ( 文档查询 | 文档层次 | 自带搜索工具 | 帮助命令 | 学习导引 )
  2. 【Flutter】Image 组件 ( 加载网络图片 | 加载静态图片 | 加载本地图片 | path_provider 插件 )
  3. 【Android 安全】DEX 加密 ( 阶段总结 | 主应用 | 代理 Application | Java 工具 | 代码示例 ) ★
  4. 【Android RTMP】安卓直播推流总结 ( 直播服务器搭建 | NV21 图像采集 | H.264 视频编码 | PCM 音频采集 | AAC 音频编码 | RTMP 包封装推流 )
  5. 【问题解决方案】ImportError: No module named 'openpyxl'/‘xlrd’
  6. 实时机器学习是什么,面临哪些挑战?
  7. 用 Python 实现文件查找
  8. 自己动手实现一个MVVM库
  9. 织梦dedecms dede plus文件作用介绍及安全设置
  10. 微信公众平台入门开发教程.Net(C#)框架