2015-12-24 68 views
3

我很难弄清楚如何使用os/exec包运行多个命令。我拖了网和stackoverflow,并没有发现任何东西适用于我的情况。这里是我的来源:在同一个shell中运行多个Exec命令golang

package main 

import (
    _ "bufio" 
    _ "bytes" 
    _ "errors" 
    "fmt" 
    "log" 
    "os" 
    "os/exec" 
    "path/filepath" 
) 

func main() { 
    ffmpegFolderName := "ffmpeg-2.8.4" 
    path, err := filepath.Abs("") 
    if err != nil { 
     fmt.Println("Error locating absulte file paths") 
     os.Exit(1) 
    } 

    folderPath := filepath.Join(path, ffmpegFolderName) 

    _, err2 := folderExists(folderPath) 
    if err2 != nil { 
     fmt.Println("The folder: %s either does not exist or is not in the same directory as make.go", folderPath) 
     os.Exit(1) 
    } 
    cd := exec.Command("cd", folderPath) 
    config := exec.Command("./configure", "--disable-yasm") 
    build := exec.Command("make") 

    cd_err := cd.Start() 
    if cd_err != nil { 
     log.Fatal(cd_err) 
    } 
    log.Printf("Waiting for command to finish...") 
    cd_err = cd.Wait() 
    log.Printf("Command finished with error: %v", cd_err) 

    start_err := config.Start() 
    if start_err != nil { 
     log.Fatal(start_err) 
    } 
    log.Printf("Waiting for command to finish...") 
    start_err = config.Wait() 
    log.Printf("Command finished with error: %v", start_err) 

    build_err := build.Start() 
    if build_err != nil { 
     log.Fatal(build_err) 
    } 
    log.Printf("Waiting for command to finish...") 
    build_err = build.Wait() 
    log.Printf("Command finished with error: %v", build_err) 

} 

func folderExists(path string) (bool, error) { 
    _, err := os.Stat(path) 
    if err == nil { 
     return true, nil 
    } 
    if os.IsNotExist(err) { 
     return false, nil 
    } 
    return true, err 
} 

我想要像我从终端的命令。 cd path; ./configure; make 所以我需要按顺序运行每个命令,然后等待最后一条命令完成后再继续。使用我当前版本的代码,它目前说./configure: no such file or directory我认为这是因为cd路径执行并在一个新的shell中执行./configure,而不是与前一个命令位于同一个目录中。有任何想法吗? UPDATE我通过改变工作目录,然后执行./configure和make命令

err = os.Chdir(folderPath) 
    if err != nil { 
     fmt.Println("File Path Could not be changed") 
     os.Exit(1) 
    } 

不过现在我很好奇,想知道是否有在同一个shell执行命令的方式来解决这个问题。

回答

14

如果你想单壳实例中运行多个命令,你需要像这样的东西来调用外壳:

cmd := exec.Command("/bin/sh", "-c", "command1; command2; command3; ...") 
err := cmd.Run() 

这将让shell来解释给定的命令。它也可以让你执行shell之类的东西,比如cd。请注意,以安全的方式将用户数据替换为这些命令可能不是微不足道的。

如果您只是想在特定目录中运行命令,则可以在没有shell的情况下执行该命令。您可以设置当前工作目录执行命令,如下所示:

config := exec.Command("./configure", "--disable-yasm") 
config.Dir = folderPath 
build := exec.Command("make") 
build.Dir = folderPath 

...并继续像以前一样。

+0

谢谢你的回答。我特别感谢你的第一个建议。我偶然发现了你的第二个建议,并且正在使用它。 – reticentroot

+0

@詹姆斯我尝试了你的建议。 command:= exec.Command(“echo * tar.gz | xargs -n1 tar zxf”) command.Dir = pathFinal cmdErr:= command.Run() 这不适用于我的另一种命令, 命令:=“cd”+ pathFinal +“;”+“echo * tar.gz | xargs -n1 tar zxf” cmd:= exec.Command(“/ bin/sh”,“-c”,command) This is working 。我想以第一种方式实施它。我不知道它为什么不起作用。 – supriya

+0

它引发错误: 解压文件失败:exec:“echo * tar.gz | xargs -n1 tar zxf”:可执行文件未在$ PATH中找到 – supriya