在Go语言中,在同一个shell中运行多个exec命令。

huangapple go评论114阅读模式
英文:

Run Multiple Exec Commands in the same shell golang

问题

我在使用os/exec包时遇到了一些问题,无法弄清楚如何运行多个命令。我在网络和stackoverflow上搜索了很多,但没有找到适用于我的情况的解决方法。这是我的源代码:

  1. package main
  2. import (
  3. _ "bufio"
  4. _ "bytes"
  5. _ "errors"
  6. "fmt"
  7. "log"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. )
  12. func main() {
  13. ffmpegFolderName := "ffmpeg-2.8.4"
  14. path, err := filepath.Abs("")
  15. if err != nil {
  16. fmt.Println("Error locating absulte file paths")
  17. os.Exit(1)
  18. }
  19. folderPath := filepath.Join(path, ffmpegFolderName)
  20. _, err2 := folderExists(folderPath)
  21. if err2 != nil {
  22. fmt.Printf("The folder: %s either does not exist or is not in the same directory as make.go\n", folderPath)
  23. os.Exit(1)
  24. }
  25. cd := exec.Command("cd", folderPath)
  26. config := exec.Command("./configure", "--disable-yasm")
  27. build := exec.Command("make")
  28. cd_err := cd.Start()
  29. if cd_err != nil {
  30. log.Fatal(cd_err)
  31. }
  32. log.Printf("Waiting for command to finish...")
  33. cd_err = cd.Wait()
  34. log.Printf("Command finished with error: %v", cd_err)
  35. start_err := config.Start()
  36. if start_err != nil {
  37. log.Fatal(start_err)
  38. }
  39. log.Printf("Waiting for command to finish...")
  40. start_err = config.Wait()
  41. log.Printf("Command finished with error: %v", start_err)
  42. build_err := build.Start()
  43. if build_err != nil {
  44. log.Fatal(build_err)
  45. }
  46. log.Printf("Waiting for command to finish...")
  47. build_err = build.Wait()
  48. log.Printf("Command finished with error: %v", build_err)
  49. }
  50. func folderExists(path string) (bool, error) {
  51. _, err := os.Stat(path)
  52. if err == nil {
  53. return true, nil
  54. }
  55. if os.IsNotExist(err) {
  56. return false, nil
  57. }
  58. return true, err
  59. }

我想要像在终端中一样执行命令:cd path; ./configure; make。所以我需要按顺序运行每个命令,并在最后一个命令完成后等待再继续执行。根据我当前的代码版本,它目前显示./configure: no such file or directory。我猜这是因为cd path执行后,在一个新的shell中执行./configure,而不是在前一个命令的同一目录中执行。有什么想法吗?
更新 我通过更改工作目录并执行./configuremake命令来解决了这个问题。

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

但我仍然很好奇是否有一种方法可以在同一个shell中执行命令。

英文:

I'm having trouble figuring out how to run multiple commands using the os/exec package. I've trolled the net and stackoverflow and haven't found anything that works for me case. Here's my source:

  1. package main
  2. import (
  3. _ "bufio"
  4. _ "bytes"
  5. _ "errors"
  6. "fmt"
  7. "log"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. )
  12. func main() {
  13. ffmpegFolderName := "ffmpeg-2.8.4"
  14. path, err := filepath.Abs("")
  15. if err != nil {
  16. fmt.Println("Error locating absulte file paths")
  17. os.Exit(1)
  18. }
  19. folderPath := filepath.Join(path, ffmpegFolderName)
  20. _, err2 := folderExists(folderPath)
  21. if err2 != nil {
  22. fmt.Println("The folder: %s either does not exist or is not in the same directory as make.go", folderPath)
  23. os.Exit(1)
  24. }
  25. cd := exec.Command("cd", folderPath)
  26. config := exec.Command("./configure", "--disable-yasm")
  27. build := exec.Command("make")
  28. cd_err := cd.Start()
  29. if cd_err != nil {
  30. log.Fatal(cd_err)
  31. }
  32. log.Printf("Waiting for command to finish...")
  33. cd_err = cd.Wait()
  34. log.Printf("Command finished with error: %v", cd_err)
  35. start_err := config.Start()
  36. if start_err != nil {
  37. log.Fatal(start_err)
  38. }
  39. log.Printf("Waiting for command to finish...")
  40. start_err = config.Wait()
  41. log.Printf("Command finished with error: %v", start_err)
  42. build_err := build.Start()
  43. if build_err != nil {
  44. log.Fatal(build_err)
  45. }
  46. log.Printf("Waiting for command to finish...")
  47. build_err = build.Wait()
  48. log.Printf("Command finished with error: %v", build_err)
  49. }
  50. func folderExists(path string) (bool, error) {
  51. _, err := os.Stat(path)
  52. if err == nil {
  53. return true, nil
  54. }
  55. if os.IsNotExist(err) {
  56. return false, nil
  57. }
  58. return true, err
  59. }

I want to the command like I would from terminal. cd path; ./configure; make
So I need run each command in order and wait for the last command to finish before moving on. With my current version of the code it currently says that ./configure: no such file or directory I assume that is because cd path executes and in a new shell ./configure executes, instead of being in the same directory from the previous command. Any ideas?
UPDATE I solved the issue by changing the working directory and then executing the ./configure and make command

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

Still now i'm curious to know if there is a way to execute commands in the same shell.

答案1

得分: 41

如果你想在单个shell实例中运行多个命令,你需要使用类似以下的方式调用shell:

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

这将让shell解释给定的命令。它还可以让你执行像cd这样的shell内置命令。请注意,以安全的方式将用户数据替换到这些命令中可能并不容易。

如果你只想在特定目录中运行命令,你可以不使用shell来实现。你可以设置当前工作目录来执行命令,像这样:

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

...然后继续你之前的操作。

英文:

If you want to run multiple commands within a single shell instance, you will need to invoke the shell with something like this:

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

This will get the shell to interpret the given commands. It will also let you execute shell builtins like cd. Note that this can be non-trivial to substitute in user data to these commands in a safe way.

If instead you just want to run a command in a particular directory, you can do that without the shell. You can set the current working directory to execute the command like so:

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

... and continue on like you were before.

huangapple
  • 本文由 发表于 2015年12月25日 07:01:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/34458625.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定