Go - 使用goroutines和Store&执行Bash命令n次打印结果

时间:2016-10-25 19:02:01

标签: bash go goroutine

我对Golang一般都很陌生,我尝试执行bash command with its arguments n times,然后将Output存储在变量{{1}中它。

我能够只做一次,或者只使用Print,如下所示:

loops

这很好用,我可以轻松阅读package main import ( "fmt" "os/exec" "os" "sync" ) func main() { //Default Output var ( cmdOut []byte err error ) //Bash Command cmd := "./myCmd" //Arguments to get passed to the command args := []string{"arg1", "arg2", "arg3"} //Execute the Command if cmdOut, err = exec.Command(cmd, args...).Output(); err != nil { fmt.Fprintln(os.Stderr, "There was an error running "+cmd+" "+args[0]+args[1]+args[2], err) os.Exit(1) } //Store it sha := string(cmdOut) //Print it fmt.Println(sha) }

现在,我想使用outputn次重复此操作。

我尝试按照回答How would you define a pool of goroutines to be executed at once in Golang?但我无法使其正常工作的人采用相同的方法。

这是我到目前为止所做的:

goroutines

但是,我并没有真正找到如何存储已执行命令的package main import ( "fmt" "os/exec" "sync" ) func main() { //Bash Command cmd := "./myCmd" //Arguments to get passed to the command args := []string{"arg1", "arg2", "arg3"} //Common Channel for the goroutines tasks := make(chan *exec.Cmd, 64) //Spawning 4 goroutines var wg sync.WaitGroup for i := 0; i < 4; i++ { wg.Add(1) go func() { for cmd := range tasks { cmd.Run() } wg.Done() }() } //Generate Tasks for i := 0; i < 10; i++ { tasks <- exec.Command(cmd, args...) //Here I should somehow print the result of the latter command } close(tasks) // wait for the workers to finish wg.Wait() fmt.Println("Done") } 并打印它。

我如何实现这一目标?

在此先感谢您对此问题的任何澄清,请发表评论。

1 个答案:

答案 0 :(得分:3)

所以以下修复了你的问题

  • 您可以调用Cmd.Output()来获取命令的输出。 否则你可以将Cmd.StdOutPipe管道连接到byte.Buffer 示例并从中读取。

  • 你的goroutine逻辑错了。它只会执行4次因为waitgroup将是Done()而main将退出。从master关闭通道是正确的,以指示工作人员退出for range循环。 wg.Done应该在那之后调用,所以我推迟了它。

  • 使用go命令执行匿名函数时,尽量不要从父作用域捕获任何内容。它可能导致灾难。而是找出你想要的参数并将它们传递给函数。

`

Sub simpleXlsMerger()
Dim bookList As Workbook
Dim mergeObj As Object, dirObj As Object, filesObj As Object, everyObj As Object
Application.ScreenUpdating = False
Set mergeObj = CreateObject("Scripting.FileSystemObject")

'change folder path of excel files here
Set dirObj = mergeObj.Getfolder("directory\path")
Set filesObj = dirObj.Files
For Each everyObj In filesObj
Set bookList = Workbooks.Open(everyObj)

'change "A2" with cell reference of start point for every files here
'for example "B3:IV" to merge all files start from columns B and rows 3
'If you're files using more than IV column, change it to the latest column
'Also change "A" column on "A65536" to the same column as start point
Range("A2:C" & Range("A65536").End(xlUp).Row).Copy
ThisWorkbook.Worksheets(1).Activate

'Do not change the following column. It's not the same column as above
Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial
Application.CutCopyMode = False
bookList.Close
Next
End Sub

`