来源:《Go 夜读》微信群
时间:2018-08-02
答:
package main
import (
"fmt"
"os/exec"
)
func main(){
command := "./dir_size.sh" //脚本的路径
cmd := exec.Command("/bin/bash", "-c", command)
output, err := cmd.Output()
if err != nil {
fmt.Printf("Execute Shell:%s failed with error:%s", command, err.Error())
return
}
fmt.Printf("Execute Shell:%s finished with output:\n%s", command, string(output))
}
其中 Command 源代码是:
func Command(name string, arg ...string) *Cmd {
cmd := &Cmd{
Path: name,
Args: append([]string{name}, arg...),
}
if filepath.Base(name) == name {
if lp, err := LookPath(name); err != nil {
cmd.lookPathErr = err
} else {
cmd.Path = lp
}
}
return cmd
}
其中 name 是执行的命令,args是参数,所以传递参数可以直接写 cmd := exec.Command("/bin/bash", "-c", "参数1","参数","参数")
这样就可以,arg...
为可变参数。
要理解为什么要这么传参,就要理解 bash -c
的用法
bash -c
传参的方法:
用法: bash -c "cmd string"
通常使用 shell 去运行脚本,两种方法 bash xxx.sh
,另外一种就是 bash -c "cmd string"
。
对于 bash xxx.sh
,首先 bash
会在当前目录去寻找 xxx.sh
,如果找到,就直接运行,找不到则按照环境变量 $PATH
的指定路径,按顺序去找,如果找到,则执行,找不到则报错。
shell 脚本的参数 $0 就是要执行的 shell 脚本 xxx.sh
, $1 就是后面紧跟 xxx.sh
的参数,$2 $3依次类推。
而对于 bash -c "cmd string"
-c If the -c option is present, then commands are read from the first non-option argument command_string. If there are arguments after the command_string, they are assigned to the positional parameters, starting with $0.
大致意思就是,如果用 -c
那么 bash 会从第一个非选项参数后面的字符串中读取命令,如果字符串有多个空格,第一个空格前面的字符串是要执行的命令,也就是 $0,后面的是参数,即 $1, $2...