持续从exec.Cmd输出中读取

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

continuously reading from exec.Cmd output

问题

大家好,我正在尝试根据命令输出选择新的行,但我总是以同步方式完成(必须等待脚本完成)。我尝试使用fsnotify,但它只适用于常规文件,你有任何想法如何实现吗?

package main
import (
   "fmt"
   "os/exec"
   "bytes"
   "os"
)

func main() {
   cmd := exec.Command("scripts/long_script")
   output := new(bytes.Buffer)
   cmd.Stdout = output
   cmd.Stderr = output
   if err := cmd.Start(); err != nil{ // 在启动后,程序继续执行,脚本在后台执行
     fmt.Printf("Failed to start " + err.Error())
     os.Exit(1)
   }
   fmt.Printf(" Before WAIT %s \n", output.String())  // 脚本正在写入,但无法从输出中读取
   cmd.Wait()
   fmt.Printf(" After Wait %s \n", output.String())  // 如果我们等待执行完成,就可以读取所有输出
}

希望对你有帮助!

英文:

Guys I am trying pick new lines as they come from command output, but always I end up doing it synchronous way (I have to wait until script is finished). I tired to use fsnotify but it is working only with regular files, do you have any idea how it can be done ?

package main
import (
   "fmt"
   "os/exec"
   "bytes"
   "os"
)

func main() {
   cmd := exec.Command("scripts/long_script")
   output := new(bytes.Buffer)
   cmd.Stdout = output
   cmd.Stderr = output
   if err := cmd.Start(); err != nil{ // after Start program is continued and script is executing in background
     fmt.Printf("Failed to start " + err.Error())
     os.Exit(1)
   }
   fmt.Printf(" Before WAIT %s \n", output.String())  // script is writing but nothing can be read from output
   cmd.Wait()
   fmt.Printf(" After Wait %s \n", output.String())  // if we wait to finish execution, we can read all output
}

答案1

得分: 6

你应该使用os.StdoutPipe()。

func main() {
    for i := 10; i < 20; i++ {
        go printName(`我的名字是Bob,我今年` + strconv.Itoa(i) + `岁`)
        // 添加延迟以便看到逐步输出
        time.Sleep(60 * time.Millisecond)
    }
    // 添加延迟以便让程序完成
    // 请使用通道或等待组
    time.Sleep(100 * time.Millisecond)
}

func printName(jString string) {
    cmd := exec.Command("echo", "-n", jString)
    cmdReader, err := cmd.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }
    scanner := bufio.NewScanner(cmdReader)
    go func() {
        for scanner.Scan() {
            fmt.Println(scanner.Text())
        }
    }()
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    if err := cmd.Wait(); err != nil {
        log.Fatal(err)
    }
}

帮助我解决问题的资源:
nathanleclaire.com
blog.kowalczyk.info

英文:

You should use os.StdoutPipe()

func main() {
    for i := 10; i &lt; 20; i++ {
	    go printName(`My name is Bob, I am ` + strconv.Itoa(i) + ` years old`)
        // Adding delay so as to see incremental output
        time.Sleep(60 * time.Millisecond)
    }
    // Adding delay so as to let program complete
    // Please use channels or wait groups
    time.Sleep(100 * time.Millisecond)
}

func printName(jString string) {
    cmd := exec.Command(&quot;echo&quot;, &quot;-n&quot;, jString)
    cmdReader, err := cmd.StdoutPipe()
    if err != nil {
	    log.Fatal(err)
    }
    scanner := bufio.NewScanner(cmdReader)
    go func() {
	    for scanner.Scan() {
		    fmt.Println(scanner.Text())
	    }
    }()
    if err := cmd.Start(); err != nil {
	    log.Fatal(err)
    }
    if err := cmd.Wait(); err != nil {
	    log.Fatal(err)
    }
}

sources that helped me:
nathanleclaire.com
blog.kowalczyk.info

答案2

得分: 5

最终我使用[]bytes成功完成了它。

stdout, err := cmd.StdoutPipe()
buff := make([]byte, 10)
var n int
for err == nil {
    n, err = stdout.Read(buff)
    if n > 0 {
        fmt.Printf("已读取 %d 个字符 %s", n, string(buff[:n]))
    }
}
cmd.Wait()
if cmd.ProcessState.Success() { // 在 Wait 后设置 ProcessState
    fmt.Println("脚本执行成功")
} else {
    fmt.Println("脚本执行失败")
}
英文:

eventually I managed to do it with []bytes

stdout, err := cmd.StdoutPipe()
buff := make([]byte,10)
var n int
for err == nil {
	n,err = stdout.Read(buff)
	if n &gt; 0{
		fmt.Printf(&quot;taken %d chars %s&quot;,n,string(buff[:n]))
	}
}
cmd.Wait()
if cmd.ProcessState.Success() {. // ProcessState is set after Wait
	fmt.Println(&quot;Script success&quot;)  
} else {
	fmt.Println(&quot;Script failed&quot;)
}

huangapple
  • 本文由 发表于 2017年4月26日 21:26:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/43635611.html
匿名

发表评论

匿名网友

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

确定